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.

Tags:

C

Assembly

X86