Strings
Byte strings, lengths, terminators, buffers, and the string instructions.
x86 string instructions are tiny pointer loops built into the instruction set. They use rsi, rdi, and rcx by convention, with the direction flag deciding which way the pointers move.
Copy bytes with rep movsb
Load the source address into rsi, the destination into rdi, and the byte count into rcx. rep repeats movsb until the count reaches zero.
lea rsi, strsrc_00
lea rdi, strdst_00
mov rcx, sizeof strsrc_00
cld
rep movsb
Keep in mind: Use cld before string work unless your calling context explicitly guarantees the direction flag.
Load, transform, store
lodsb loads one source byte into al and advances rsi. stosb writes al to the destination and advances rdi. The loop below turns the lowercase ASCII bytes into uppercase in place.
lea rsi, strsrc_02
mov rdi, rsi
mov rcx, lengthof strsrc_02
cld
start3:
lodsb
sub al, 32
stosb
dec rcx
jnz start3
Keep in mind: The subtraction by 32 relies on ASCII's fixed gap between lowercase and uppercase letters.
Search with repne scasb
scasb compares al with the byte at rdi. The repne prefix keeps scanning while bytes differ and the count remains nonzero.
mov al, 'b'
lea rdi, strsrc_03
mov rcx, lengthof strsrc_03
cld
repne scasb
jnz absent
mov found, 1
jmp finish
absent:
mov found, 0
finish:
Keep in mind: After the scan, the zero flag tells you whether a matching byte was found.
Compare two buffers
cmpsb compares the bytes addressed by rsi and rdi. With repe, comparison stops on the first mismatch or when the count reaches zero.
lea rsi, strsrc_04
lea rdi, strdst_04
mov rcx, sizeof strsrc_04
cld
repe cmpsb
jnz differ
mov match, 1
jmp finish_01
differ:
mov match, 0
finish_01:
Keep in mind: Always pair a buffer comparison with an explicit length; raw bytes have no automatic terminator.
Keep these rules
- String instructions use implicit pointer and count registers.
- cld makes traversal move toward higher addresses.
- rep, repe, and repne express different repetition conditions.