Intel IA-32 Assembly Tutorial

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.

 byteworddword
move array data:MOVSBMOVSWMOVSD
compare arrays:CMPSBCMPSWCMPSD
scan array:SCASBSCASWSCASD
store array data:STOSBSTOSWSTOSD
load accumulator:LODSBLODSWLODSD

The REP prefix repeats a string primitive instruction while ECX is greater than zero.

REPRepeat while ECX > 0
REPZ, REPERepeat while ECX > 0 and Zero flag is set
REPNZ, REPNERepeat 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
<< < [Page 12 of 14] > >>