27

I am a little bit confused about the difference between

leal -4(%ebp), %eax       

and

movl -4(%ebp), %eax

Can someone explain this to me?

Peter Cordes
  • 286,368
  • 41
  • 520
  • 731
Serguei Fedorov
  • 7,285
  • 9
  • 61
  • 91
  • 2
    related: http://stackoverflow.com/questions/4003894/leal-assembler-instruction – mensi Jun 26 '12 at 17:12
  • 2
    and kind of duplicate: http://stackoverflow.com/questions/1658294/x86-asm-whats-the-purpose-of-the-lea-instruction – mensi Jun 26 '12 at 17:15
  • 2
    The clue is in the name. Load Effective Address only loads the address. – harold Jun 26 '12 at 17:21
  • 2
    I'd advise to read the friendly CPU manual. And you have a choice: from Intel or from AMD. – Alexey Frunze Jun 26 '12 at 19:52
  • @PrateekGupta The tag you added doesn't make sense. It is part of the answer, not part of the question. If the OP had known that tag was apposite, he would have known the answer and not asked the question. – user207421 Apr 20 '19 at 08:37

4 Answers4

57

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.

Adam Rosenfield
  • 375,615
  • 96
  • 501
  • 581
8

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.

FrankH.
  • 17,041
  • 2
  • 42
  • 62
2

Equivialent to LEA in Intel syntax, load effective address (long?).

zxcdw
  • 1,601
  • 1
  • 10
  • 18
-2

Both LEA and MOV can load a register with the offset to a variable for instance.

MOV can also transfer the content of a memory place to a register, LEA can't. Both LEA & MOV can calculate "effective offsets" which can be used to do math much more effective

hell
  • 1
  • 2
  • This is not really useful, compared to the other answers that have been up for three years. I would recommend that you try answering relatively new questions, or ones without an accepted answer, unless you have something really novel and useful to add. – Tom Zych Jan 15 '16 at 12:15
  • You're talking about `mov reg, imm32` like `mov eax, OFFSET var` for the address of a *static* variable. This is a confusing answer because the question shows access to a C *local* variable on the stack, relative to EBP. `mov` can't put those addresses into registers. Also, only LEA can do any math itself, and it's the *assembler + linker* which actually *calculate* the "effective offset" to fill in as an immediate. `mov r32, imm32` just copies bits into a register. (More efficiently than `lea r32, [disp32]`, so the only use case you mention for LEA is one you shouldn't use it for.) – Peter Cordes Apr 20 '19 at 10:15