PROWAREtech
Intel IA-32 Assembly Tutorial - A Guide to the Basics of x86 Assembly - Page 06
Data-Related Operators and Directives
OFFSET
operator returns the offset of a data label. The offset represents the distance in bytes of the label from
the beginning of the data segment.
.data
byt BYTE ?
wrd WORD ?
dbl DWORD ?
array WORD 1,2,3,4,5,6,7,8,9
.code
mov esi,OFFSET byt ;assume byt located at 00808000h = ESI
mov esi,OFFSET wrd ;00808001h = ESI
mov esi,OFFSET dbl ;00808003h = ESI
mov esi,OFFSET array + 6 ;0080800Dh = ESI
The ALIGN
directive is used to align a variable on an even-numbered address in memory because the CPU can
access these variables faster.
.data
byt BYTE ? ;00808000h
ALIGN 2
wrd WORD ? ;00808002h
dbl DWORD ? ;00808004h
Use the PTR
directive to override the default size of an operand.
.data
dbl DWORD 12345678h
wdbl WORD 5678h,1234h
.code
mov al,BYTE PTR dbl ;al = 78h
mov al,BYTE PTR [dbl+1] ;al = 56h
mov al,BYTE PTR [dbl+2] ;al = 34h
mov al,BYTE PTR [dbl+3] ;al = 12h
mov eax,DWORD PTR wdbl ;eax = 12345678h
The TYPE
operator returns the size in bytes of a single element of a variable.
The LENGTHOF
operator returns the number of elements in an array.
Using the SIZEOF
operator is the same as multiplying LENGTHOF
by TYPE
.
The LABEL
directive can be used to construct a larger integer from to smaller ones and vice-versa.
.data
wordword LABEL DWORD
var1 WORD 5678h
var2 WORD 1234h
.code
mov eax,wordword ;EAX = 12345678h
Indirect Addressing
By using a register as a pointer to access an array is called indirect addressing.
.data
val BYTE Fh
.code
mov esi,OFFSET val
mov al,[esi] ;al = Fh, [esi] is a pointer and this only works on registers
The assembler does not know whether ESI
points to a BYTE, WORD or DWORD. The PTR
operator
tells the assembler what a registry points to. Note: EAX, EBX, ECX, EDX, etc. could have been used with the same results.
inc [esi] ;DOES NOT WORK!
inc BYTE PTR [esi]
Indirect operands are needed to deal with arrays.
.data
bytearray BYTE 1,2,3,4,5,6,7,8
wordarray WORD 10,11,12,13,14,15,16
.code
mov esi,OFFSET bytearray
mov al,[esi] ;AL = 1
add esi,1 ;increment by 1 (byte)
mov al,[esi] ;AL = 2
add esi,1 ;increment by 1 (byte)
mov al,[esi] ;AL = 3
mov esi,OFFSET wordarray
mov al,[esi] ;AL = 10
add esi,2 ;increment by 2 (bytes)
mov al,[esi] ;AL = 11
add esi,2 ;increment by 2 (bytes)
mov al,[esi] ;AL = 12
An indexed operand adds a constant to a register to generate an effective address.
.data
bytearray BYTE 1,2,3,4,5,6,7,8
wordarray WORD 10,11,12,13,14,15,16
.code
mov esi,OFFSET bytearray
mov al,[esi] ;AL = 1
mov al,[esi+1] ;AL = 2
mov al,[esi+2] ;AL = 3
mov esi,OFFSET wordarray
mov al,[esi] ;AL = 10
mov al,[esi+2] ;AL = 11
mov al,[esi+4] ;AL = 12
A variable that contains the address of another variable is a pointer.
.data
bytearray BYTE "Hello World!",0
ptrbyte DWORD OFFSET bytearray
This little code snippet demonstrates loading the address of a variable that points to a DWORD
into the ESI
register. It then increments the variable pointed to by one and then moves that value
into the EAX
register.
mov esi,[esp+8]
inc DWORD PTR [esi]
mov eax,DWORD PTR [esi]
This code snippet demonstrates an easy way of traversing an array of DWORD
values. It uses EAX
× 4 (bytes) as an index into the array.
mov esi,[esp+8]
xor eax, eax ; eax = 0
loop_start:
inc DWORD PTR [esi+eax*4] ; increment the value in the array by one
inc eax ; increment the index into the array
cmp eax, 100
jne loop_start ; stop looping when eax = 100
The TYPEDEF
operator creates a user-defined type. TYPEDEF
is useful
for creating pointer variables. This example creates new data types that are pointers:
PBYTE TYPEDEF PTR BYTE
PWORD TYPEDEF PTR WORD
PDWORD TYPEDEF PTR DWORD
The JMP
instruction jumps unconditionally to a code label and the LOOP
instruction repeats a block of statements a specified number of times. A LOOP
instruction must jump between -128 to +127 bytes. Instructions have an average size of 3 bytes.
.data
.code
lblBegin:
xor edx,edx ;edx = 0
mov ecx,10 ;ecx is used by LOOP as a counter
lblLoop:
inc edx
loop lblLoop ;first subtract 1 from ecx then if ecx is zero stop looping otherwise jump to lblLoop
jmp lblBegin ;jmp unconditionally to the label lblBegin
Example copying a string from a source to a destination using the LOOP
instruction:
.data
sour BYTE "copy me to a new place in memory.",0
dest BYTE SIZEOF sour DUP(0),0
.code
xor esi,esi
mov ecx,SIZEOF sour
lblLoop:
mov al,sour[esi]
mov dest[esi],al
add esi,1
loop lblLoop