What does the LEAL assembly instruction do?
Equivialent to LEA
in Intel syntax, load effective address (long?).
LEA (load effective address) just computes the address of the operand, it does not actually dereference it. Most of the time, it's just doing a calculation like a combined multiply-and-add for, say, array indexing.
In this case, it's doing a simple numeric subtraction: leal -4(%ebp), %eax
just assigns to the %eax
register the value of %ebp - 4
. It's equivalent to a single sub
instruction, except a sub
requires the destination to be the same as one of the sources.
The movl
instruction, in contrast, accesses the memory location at %ebp - 4
and stores that value into %eax
.
If you wish to look at this in terms of a different programming language, then:
int var;
[ ... ]
func (var, &var);
evaluates to the following (Linux x86_64) assembly code:
[ ... ] 4: 8b 7c 24 0c mov 0xc(%rsp),%edi 8: 48 8d 74 24 0c lea 0xc(%rsp),%rsi d: e8 xx xx xx xx callq ... <func> [ ... ]
Since %rdi
/ %rsi
are the 1st / 2nd arguments, you can see that lea ...
retrieves the address &var
of a variable, while mov ...
loads/stores the value var
of the same.
I.e. in assembly, the use of lea
instead of mov
is similar to using the address-of &
operator in C/C++, not the (value of) a variable itself.
lea
has far more uses than that, but you explicitly asked about the difference between the two.
For illustration: mov
with a memory operand always performs a memory access (load or store), while the memory operand to lea
is merely treated as pointer arithmetic - i.e. the address is calculated and resolved but no memory access happens at the instruction itself. These two:
lea 1234(%eax, %ebx, 8), %ecx
movl (%ecx), ecx
result in the same as:
movl 1234(%eax, %ebx, 8), %ecx
while the following:
leal (%eax, %eax, 4), %eax
multiplies the value in %eax
with five.