Page 1 of 1

purpose of lea instruction?

Posted: Fri Jan 09, 2009 1:39 pm
by yemista
Why is this instruction here? Isnt it equivalent to mov ax, label?
As long as you dont deference it should label be equivlant to an address?

Re: purpose of lea instruction?

Posted: Fri Jan 09, 2009 1:44 pm
by ru2aqare
yemista wrote:Why is this instruction here? Isnt it equivalent to mov ax, label?
As long as you dont deference it should label be equivlant to an address?
It can compute more complex addresses. Like

Code: Select all

  mov eax, index_into_jump_table
  lea eax, [offset some_variable + 4*eax]
or you could perform more complex multiplications with it:

Code: Select all

  lea ecx, [0 + 2*eax + eax] ; multiply by three
  lea ecx, [0 + 4*eax + eax] ; multiply by five
and similar things.

Re: purpose of lea instruction?

Posted: Fri Jan 09, 2009 1:54 pm
by Brendan
Hi,
yemista wrote:Why is this instruction here? Isnt it equivalent to mov ax, label?
As long as you dont deference it should label be equivlant to an address?
Indirect addressing doesn't need to be as simple as "[label]". Consider these instructions (note: the second instruction isn't legal):
  • mov eax, [esi+ebx*4+0x12345678]
  • mov edi, esi+ebx*4+0x12345678
  • lea edi, [esi+ebx*4+0x12345678]
The LEA instruction was originally intended to be used to Load the Effective Address, but because of the complex addressing supported by 80x86 CPUs it's probably used more often for fast mathematics operations. For a simple example, rather than multiplying something by 5 you could do "lea eax,[eax*4 + eax]".


Cheers,

Brendan

Re: purpose of lea instruction?

Posted: Fri Jan 09, 2009 5:29 pm
by CodeCat
When you think in C terms, then point of LEA is to support the & 'address-of' operator when used in conjunction with local variables and function parameters. These don't have labels pointing to them, so the only way to access them is by using indirect address with the ebp register as base. For example, [ebp-4] is the first local variable, [ebp-8] the second and so on, and similarly for [ebp+8] (first parameter), [ebp+12] (second parameter) etc. This is fine if you only need the values of those variables. But what if you need their addresses? You could do:

Code: Select all

mov eax, ebp
sub eax, 4
to get the address of the first local variable into eax. But with LEA, you need only one instruction to do the same:

Code: Select all

lea eax, [ebp-4]
This is faster than doing MOV and ADD, and it might even be faster than a single ADD alone! An additional benefit is that the assembly code is clearer, as the notation [ebp-4] makes it instantly clear what you're referring to.

Re: purpose of lea instruction?

Posted: Sat Jan 10, 2009 9:12 am
by bewing
To expand on Brendan's point:

Most ASM opcodes only do one tiny thing at a time. Example:
OR EAX, 0x4000

That's pitiful, isn't it? One entire opcode, and one entire machine cycle, just to set one bit in a register?

Now, as Brendan said, take a look at what I call an "addressing SIB mode".
MOV ECX, [EBX + EAX*8 + 0x12345678]

In order to do this one instruction, the CPU had to calculate an address. It took a register, shifted it by 3 bits, added it to another register, and added a constant -- all in one opcode! Isn't that amazing that it can do all that in one opcode, with dedicated circuitry, so quickly? Wouldn't it be neat if you actually had access to that math operation -- all that dedicated address calculation circuitry -- to do high-speed MATH (not just calculating addresses) in your code?

That is what the LEA address is for. Sadly, there are many times when I wish I could do:
LEA ECX, [EBX - EAX*8]
but the x86 doesn't support subtraction at all. :(

One point that I don't think Brendan emphasized enough: the other nice thing about LEA is that you can do some useful multiplications on ALL registers IN PLACE.
LEA EDI, [EDI + EDI*4]

Now, please think about how many registers you would normally have to trash, in order to multiply EDI by 5, using MUL. This works for multiplications by 3, 5, and 9. So those (surprisingly) are very efficient numbers to multiply by, in Assembly language.

Another (semi-)important note: LEA does not set or trash any EFLAGS bits. So, if you want to (say) fix your stack pointer at the end of a function, but your EFLAGS bits are already set, you can do:
LEA ESP, [ESP + 16]
Which gets rid of 4 dwords off your stack, without messing up your Carry flag (for instance).

Re: purpose of lea instruction?

Posted: Sat Jan 10, 2009 5:21 pm
by CodeCat
bewing wrote:That is what the LEA address is for. Sadly, there are many times when I wish I could do:
LEA ECX, [EBX - EAX*8]
but the x86 doesn't support subtraction at all. :(
You could negate EAX first, then it'd work.

Re: purpose of lea instruction?

Posted: Sat Jan 10, 2009 6:05 pm
by bewing
Yes, but then you're up to 2 opcodes anyway (and EFLAGS is trashed), so you might as well just use SHL and SUB for clarity at that point.