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.

Copy bytes with rep movsb source/chapters/strings.asm
    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.

Load, transform, store source/chapters/strings.asm
    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.

Search with repne scasb source/chapters/strings.asm
    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.

Compare two buffers source/chapters/strings.asm
    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.