Skip to content

Instructions

x86-64

String Operations (MOVS / STOS / LODS / SCAS / REP)

x86 string instructions operate on data pointed to by RSI/RDI and are typically combined with REP prefixes to implement bulk memory copy, fill, and scan.

x86-64 string instructions implicitly use RSI (source), RDI (destination), and RCX (count). After each operation they auto-increment or auto-decrement RSI/RDI by the operand size, depending on the direction flag (DF): DF=0 → increment (normal); DF=1 → decrement (reverse).

Instruction table

MnemonicOperationUses
MOVSB/W/D/Q[RDI] ← [RSI]; advance bothmemcpy
STOSB/W/D/Q[RDI] ← AL/AX/EAX/RAX; advance RDImemset
LODSB/W/D/QAL/AX/EAX/RAX ← [RSI]; advance RSIRead loop
SCASB/W/D/Qflags ← AL/…[RDI]; advance RDImemchr / strlen
CMPSB/W/D/Qflags ← [RSI][RDI]; advance bothmemcmp

REP prefix variants

PrefixRepeat until
REPRCX == 0
REPE / REPZRCX == 0 or ZF == 0
REPNE / REPNZRCX == 0 or ZF == 1
asm
; memset(rdi, 0, rcx) equivalent
xor  eax, eax
rep  stosb          ; store AL (0) into [RDI] RCX times

; memcpy(rdi, rsi, rcx) equivalent
rep  movsb          ; copy RCX bytes from [RSI] to [RDI]

; strlen idiom
xor  eax, eax
mov  rcx, -1
repne scasb         ; scan [RDI] for AL (0) while RCX != 0 and ZF==0
not  rcx
dec  rcx            ; rcx = length

Reverse-engineering notes

  • rep movsb / rep stosd / rep stosq in compiled code are the direct output of inlined memcpy / memset — decompilers usually reconstruct the intrinsic call.
  • The direction flag (DF) is normally 0 (cleared by CLD). If you see a STD instruction setting DF=1 before a string op, data is being processed backwards — rare in normal code but used in overlapping-buffer memmove.
  • repne scasb with rax = 0 is the canonical compiled strlen; count recovery needs the not rcx; dec rcx epilogue.
  • Some optimised libc memcpy implementations avoid rep movsb and use SSE/AVX moves instead; rep movsb re-emerged as competitive on modern CPUs with the Enhanced REP MOVSB (ERMS) feature.