I'm trying to understand the differences between the mov and lea instructions in x86 assembly language. I've written a simple assembly code snippet , and I've added comments to explain my understanding of these instructions.
.data
num: .int 2 # Declare an integer variable num with value 2
.text
.globl _start
_start:
movl num, %eax # num stores an address, take the value inside that address into eax
movl $num, %ebx # num stores an address, $ tells us to take the address itself into ebx
leal num, %ecx # num stores an address, take the address itself into ecx (lea)
#initialize
movl $0, %eax
movl $0, %ebx
movl $0, %ecx
movl $num, %edx # num stores an address, take the address itself into edx
movl %edx, %eax # edx is an address, take the value inside that address into eax
leal (%edx), %ecx # () tells us to go to the address inside edx, take the address itself into ecx (lea)
movl (%edx), %ebx # () tells us to go to the address inside edx, take the value inside that address into ebx
# Exit
movl $1, %eax # System call number for exit
xorl %ebx, %ebx # Exit status 0
int $0x80 # Invoke the syscall
However, I'm a bit confused about how these instructions work with registers. and I'll be glad if someone will give me his explanation.
Most of your comments are fine.
Others may need some rewording:
"take the value inside that address"
This just puts a copy of what is in the EDX register into the EAX register. The fact that in this case EDX contains an address is of no importance.
"go to the address inside"
We're not going to an address. The CPU calculates the address that the leftmost operand represents and stores it as such into the destination register ECX.
From a comment:
No, you can't say the same:
The
movl %eax, %eaxinstruction is a copy from one register to another. And since source and destination are the same register it is also a 'silly' operation. Now if you know that EAX contains the value 0x002000, what you wrote (movl 0x002000, %eax) is certainly not the same as that mere register copy. In your assembler the absence of the $ prefix makes the instruction de-reference, and thusmovl 0x002000, %eaxwill fetch a dword from the memory at the address 0x002000.In summary and based on num equaling 0x001000 and EAX equaling 0x002000:
Now add the $ prefix and
making this instruction the equivalent of
movl %eax, %eax.