Assembly notes - mov & lea

3 minute read

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 :

  1. First we put 0x600000 in ebx
  2. Then we put half of 0xb8 in ecx.
  3. 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.