Assembly notes - mov & lea
mov eax,thou
segment .data
thou dd 1000 ; number 1000 stored in a 4 bytes integer
segment .text
global _start
_start:
mov eax,thou
Before mov eax,thou
we have :
Address Name Content
0x6000c thou 1000
rax rax 0
After the instruction :
Address Name Content
0x6000c thou 1000
rax rax 0x6000c
mov eax,[thou]
segment .data
thou dd 1000 ; number 1000 stored in a 4 bytes integer
segment .text
global _start
_start:
mov eax,[thou]
Before mov eax,thou
we have :
Address Name Content
0x6000c thou 1000
rax rax 0
After the instruction :
Address Name Content
0x6000c thou 1000
rax rax 1000
mov edx,eax
segment .data
thou dd 1000 ; number 1000 stored in a 4 bytes integer
segment .text
global _start
_start:
mov eax,[thou]
mov edx,eax
Before mov edx,eax
we have :
Address Name Content
0x6000c thou 1000
rax rax 1000
rdx rdx 0
After the mov edx,eax
instruction :
Address Name Content
0x6000c thou 1000
rax rax 1000
rdx rdx 1000
mov edx,[eax]
segment .data
nine dd 9 ; number 9 stored in an integer
nadd dd 0x6000d0 ; the address storing the integer nine.
segment .text
global _start
_start:
mov eax,[nadd]
mov edx,[eax]
Before mov edx,[eax]
we have :
Address Name Content
0x6000d0 nine 9
0x6000d4 nadd 0x6000d0
rax rax 0x6000d0
rdx rdx 0
After the mov edx,[eax]
instruction :
Address Name Content
0x6000d0 nine 9
0x6000d4 nadd 0x6000d0
rax rax 0x6000d0
rdx rdx 9
The instruction mov edx,[eax]
generates a segmentation fault if the content of
eax (in our case it was 0x6000d0
) points to an address in memory that is forbidden.
mov in bss variable
The following code moves the number 15 in the bss variable c
.
segment .bss
c resw 1
segment .text
global start
start:
mov dword [c],15
xor eax,eax ; useless instruction used to debug previous one
Note that if we don’t correctly specify the size of the move, the program
might not behave as expected.
In our case, since 15 holds in a byte we could have used byte, word, dword,
qword as long as the value moved into c
holds in a word (2 bytes).
lea eax,[a]
lea stands for load effective address.
When doing lea eax,[a]
, the address of a will be moved to eax.
In this simple case, this is the equivalent of doing mov eax,a
.
segment .data
a dd 5
b dd 10
segment .bss
c resd 1
d resd 1
segment .text
global start
start:
lea eax,[a] ; mov eax,a would have produced the same result
xor eax,eax ; useless instruction used to debug previous one
Assembly data
0x6000bc a 5
0x6000c0 b 10
0x6000c4 c 00
0x6000c8 d 00
Before lea eax,[a]
:
rax 0
After :
rax 0x6000bc
lea,[a+4]
segment .data
a dd 5
b dd 10
segment .bss
c resd 1
d resd 1
segment .text
global start
start:
lea eax,[a+4] ;mov eax,a+4 would have produced the same result
xor eax,eax ; useless instruction used to debug previous one
Assembly data
0x6000bc a 5
0x6000c0 b 10
0x6000c4 c 00
0x6000c8 d 00
Before lea eax,[a+4]
:
rax 0
After :
rax 0x6000c0
Had we used lea eax,[a+4*2]
we would have had 0x6000c4
in rax.
And lea eax,[a+4*2+4]
would have put 0x6000c8
in rax.
Note that in these cases, using mov eax,a+4*2
and mov eax,a+4*2+4
would have
produced the same result.
As we will see, the particularity of lea
resides in the fact that it can be
used to perform math with register addresses when mov cannot.
lea eax,[ebx+ecx*2]
Here we want to put 0x6000b8
in eax.
We will do so in a convoluted way :
- First we put 0x600000 in ebx
- Then we put half of 0xb8 in ecx.
- Finally we use lea to put ebx+ecx*2 in eax.
segment .text
global start
start:
mov ebx,0x600000
mov ecx,0x5c
lea eax,[ebx+ecx*2] ; 0x5c * 2 = 0xb8
xor eax,eax ; useless instruction used to debug previous one
The result is that eax contains 0x6000b8
.
This cannot be done with mov eax, ebx+ecx*2
. The mov
instruction does not
allow mathematical operations on register addresses.
This particularity of lea
is often used to find a specific index of an array.
For instance, ebx
contains the base of the array, and then ecx
contains the
index that we want to find. If the array contains integers stored in dwords
(4 bytes) we would have to use lea eax,[ebx+ecx*4]
to get the pointer to the
array’s index.