PROWAREtech
Intel IA-32 Assembly Tutorial - A Guide to the Basics of x86 Assembly - Page 12
String (Array) Primitive Instructions
These instructions use either EDI
, ESI
, or both to address memory and they use only memory operands. These "string primitives" can repeat for processing arrays. The load accumulator instructions load AL
, AX
or EAX
.
byte | word | dword | |
move array data: | MOVSB | MOVSW | MOVSD |
compare arrays: | CMPSB | CMPSW | CMPSD |
scan array: | SCASB | SCASW | SCASD |
store array data: | STOSB | STOSW | STOSD |
load accumulator: | LODSB | LODSW | LODSD |
The REP
prefix repeats a string primitive instruction while ECX
is greater than zero.
REP | Repeat while ECX > 0 |
REPZ, REPE | Repeat while ECX > 0 and Zero flag is set |
REPNZ, REPNE | Repeat while ECX > 0 and Zero flag is clear |
MOVSB, MOVSW and MOVSD
MOVSB
, MOVSW
and MOVSD
copy bytes, words and dwords, respectively.
TITLE 'extern "C" void copybytes(void *destination, const void *source, unsigned count);'
.686
.model FLAT
PUBLIC _copybytes
_SEG SEGMENT
_copybytes PROC NEAR
; push ESI and EDI
mov ecx, DWORD PTR [esp+12] ; count
mov esi, DWORD PTR [esp+8] ; source
mov edi, DWORD PTR [esp+4] ; destination
rep movsb
; pop EDI and ESI
ret 0
_copybytes ENDP
_SEG ENDS
END
TITLE 'extern "C" void copywords(void *destination, const void *source, unsigned count);'
.686
.model FLAT
PUBLIC _copywords
_SEG SEGMENT
_copywords PROC NEAR
mov ecx, DWORD PTR [esp+12] ; count
mov esi, DWORD PTR [esp+8] ; source
mov edi, DWORD PTR [esp+4] ; destination
rep movsw
ret 0
_copywords ENDP
_SEG ENDS
END
TITLE 'extern "C" void copydwords(void *destination, const void *source, unsigned count);'
.686
.model FLAT
PUBLIC _copydwords
_SEG SEGMENT
_copydwords PROC NEAR
mov ecx, DWORD PTR [esp+12] ; count
mov esi, DWORD PTR [esp+8] ; source
mov edi, DWORD PTR [esp+4] ; destination
rep movsd
ret 0
_copydwords ENDP
_SEG ENDS
END
The CLD
and STD
instructions change the direction flag. CLD
increments
EDI
and ESI
while STD
(SeT Direction flag) decrements when using one of
the REP
prefixes.
TITLE 'extern "C" void copywords(void *destination, const void *source, unsigned count);'
.686
.model FLAT
PUBLIC _copywords
_SEG SEGMENT
_copywords PROC NEAR
mov ecx, DWORD PTR [esp+12] ; count
mov esi, DWORD PTR [esp+8] ; source
mov edi, DWORD PTR [esp+4] ; destination
cld ; CLear Direction flag (increment)
rep movsw
ret 0
_copywords ENDP
_SEG ENDS
END
CMPSB, CMPSW and CMPSD
CMPSB
, CMPSW
and CMPSD
compare bytes, words and dwords, respectively.
TITLE 'extern "C" void comparedwords(void *array1, const void *array2);'
.686
.model FLAT
PUBLIC _comparedwords
_SEG SEGMENT
_comparedwords PROC NEAR
mov esi, DWORD PTR [esp+8] ; array2
mov edi, DWORD PTR [esp+4] ; array1
cmpsd ; compare one DWORD to another DWORD
ja lbl1 ; jump if array2 > array1
jmp lbl2 ; jump since array2 <= array1
lbl1:
lbl2:
ret 0
_comparedwords ENDP
_SEG ENDS
END
Repeat prefixes can be used, too.
TITLE 'extern "C" void comparedwords(void *array1, const void *array2, unsigned count);'
.686
.model FLAT
PUBLIC _comparedwords
_SEG SEGMENT
_comparedwords PROC NEAR
mov ecx, DWORD PTR [esp+12] ; count
mov esi, DWORD PTR [esp+8] ; array2
mov edi, DWORD PTR [esp+4] ; array1
cld
repe cmpsd ; repeat while equal
ja lbl1 ; jump if array2 > array1
jmp lbl2 ; jump since array2 <= array1
lbl1:
lbl2:
ret 0
_comparedwords ENDP
_SEG ENDS
END
SCASB, SCASW and SCASD
SCASB
, SCASW
and SCASD
compare a value in
AL
, AX
, EAX
to a BYTE
, WORD
or DWORD
, respectively, addressed by EDI
. This is good for
scanning for a particular character like the null character. See
strlen
procedure or
wcslen
procedure for example.
LODSB, LODSW and LODSD
LODSB
, LODSW
and LODSD
load a BYTE
,
WORD
or DWORD
from memory at ESI
into AL
,
AX
or EAX
, respectively. ESI
is then incremented or
decremented based on the Direction flag.
STOSB, STOSW and STOSD
STOSB
, STOSW
and STOSD
store the contents of
AL
, AX
or EAX
in memory at the offset pointed to
by EDI
. EDI
is then incremented or decremented based on the
Direction flag.
This example uses both LODSD
and STOSD
.
TITLE multiply an array of integers by 11
.386
.model FLAT
.data
array DWORD 10,25,50,100,125,150,200
.code
main PROC
mov ecx, LENGTHOF array ; loop will continue while ECX > 0
cld ; direction is forward
mov esi, OFFSET array ; source
mov edi, esi ; destination (same as source)
lbl1:
lodsd ; ESI -> EAX
mul 11 ; multiply by 11
stosd ; EAX -> EDI (which is ESI)
loop lbl1 ; loop while ECX > 0
xor eax, eax
ret 0
main ENDP
END main