4.7.4 Calculating addresses of local variables
Finding the address of a label defined in the data or bss segments is
simple. Basically, the linker does this. However, calculating the address
of a local variable (or parameter) on the stack is not as straightforward.
However, this is a very common need when calling subroutines. Consider
the case of passing the address of a variable (let’s call it x) to a function
(let’s call it foo). If x is located at EBP − 8 on the stack, one cannot just
use:
mov eax, ebp - 8
Why? The value that MOV stores into EAX must be computed by the assembler
(that is, it must in the end be a constant). However, there is an
instruction that does the desired calculation. It is called LEA (for Load Effective
Address). The following would calculate the address of x and store
it into EAX:
lea eax, [ebp - 8]
Now EAX holds the address of x and could be pushed on the stack when
calling function foo. Do not be confused, it looks like this instruction is
reading the data at [EBP−8]; however, this is not true. The LEA instruction
never reads memory! It only computes the address that would be read
by another instruction and stores this address in its first register operand.
Since it does not actually read any memory, no memory size designation
(e.g. dword) is needed or allowed.