Skip to content
Assembly

strlen — Scan Until NUL

Compute C-string length by scanning memory until a zero byte.

By EZ4Code Team
stringsseoptimization

Code

; strlen(s) -> length   rdi = s, result in rax
section .text
global strlen

strlen:
    mov     rax, rdi        ; save start pointer
.loop:
    cmp     byte [rdi], 0   ; is *rdi == '\0'?
    je      .done
    inc     rdi
    jmp     .loop
.done:
    sub     rdi, rax        ; length = end - start
    mov     rax, rdi
    ret

; Optimized: process 8 bytes at a time
; (the famous 'determine if a word has a zero byte' bit trick)
global strlen_fast
strlen_fast:
    mov     rax, rdi
    and     rdi, -8         ; align to 8-byte boundary
    pxor    xmm0, xmm0
.loop:
    movdqu  xmm1, [rax]     ; load 16 bytes (unaligned)
    pcmpeqb xmm1, xmm0      ; compare with 0 -> 0xFF bytes on match
    pmovmskb ecx, xmm1      ; pack match bits into ecx
    test    ecx, ecx
    jnz     .found
    add     rax, 16
    jmp     .loop
.found:
    bsf     ecx, ecx        ; bit index of first 0
    add     rax, rcx
    ret

Explanation

The naive strlen walks byte-by-byte until NUL. The fast version uses SSE2: pcmpeqb compares 16 bytes against zero in parallel, pmovmskb packs the result into a 16-bit mask, and bsf (bit scan forward) finds the first set bit. This is the technique glibc uses for its SIMD strlen. Note that strict C allows reading one byte past the NUL, so the vectorized version must be careful at page boundaries.

More Assembly Snippets