strlen — Scan Until NUL
Compute C-string length by scanning memory until a zero byte.
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
retExplanation
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
Hello World via Linux syscall
A freestanding x86-64 program that prints and exits using only kernel syscalls.
Function Call Convention (System V AMD64)
Pass args in registers, preserve callee-saved regs, keep rsp 16-byte aligned.
Loop Summation (1..N)
Sum integers 1..N with a counted loop using dec/jnz.
memcpy — Copy with rep movsb
Use the rep movsb string instruction for a tight memory copy.
Bit Manipulation: popcount, ctz, abs
Use BMI/ABM instructions for branchless bit operations.
Read a File via syscalls
open/read/write/close a file using only Linux syscalls.