Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of the LEA instruction?

For me, it just seems like a funky MOV. What's its purpose and when should I use it?

like image 636
user200557 Avatar asked Nov 01 '09 20:11

user200557


People also ask

What is the purpose of LEA instruction?

The LEA (Load Effective Address) instruction is a way of obtaining the address which arises from any of the Intel processor's memory addressing modes. it moves the contents of the designated memory location into the target register.

What is the purpose of LEA instruction in 8086?

LEA − Used to load the address of operand into the provided register. LES − Used to load ES register and other provided register from the memory.

What is Lea used for in Assembly?

The lea (load effective address) instruction is used to put a memory address into the destination.

What is the difference between MOV and LEA instruction?

MOV computes an address, using x86's rather rich set of addressing modes, and then either reads or writes the data at that address. LEA computes an address by the same means, and then stores the address itself in the target register.


2 Answers

As others have pointed out, LEA (load effective address) is often used as a "trick" to do certain computations, but that's not its primary purpose. The x86 instruction set was designed to support high-level languages like Pascal and C, where arrays—especially arrays of ints or small structs—are common. Consider, for example, a struct representing (x, y) coordinates:

struct Point {      int xcoord;      int ycoord; }; 

Now imagine a statement like:

int y = points[i].ycoord; 

where points[] is an array of Point. Assuming the base of the array is already in EBX, and variable i is in EAX, and xcoord and ycoord are each 32 bits (so ycoord is at offset 4 bytes in the struct), this statement can be compiled to:

MOV EDX, [EBX + 8*EAX + 4]    ; right side is "effective address" 

which will land y in EDX. The scale factor of 8 is because each Point is 8 bytes in size. Now consider the same expression used with the "address of" operator &:

int *p = &points[i].ycoord; 

In this case, you don't want the value of ycoord, but its address. That's where LEA (load effective address) comes in. Instead of a MOV, the compiler can generate

LEA ESI, [EBX + 8*EAX + 4] 

which will load the address in ESI.

like image 145
I. J. Kennedy Avatar answered Oct 20 '22 08:10

I. J. Kennedy


From the "Zen of Assembly" by Abrash:

LEA, the only instruction that performs memory addressing calculations but doesn't actually address memory. LEA accepts a standard memory addressing operand, but does nothing more than store the calculated memory offset in the specified register, which may be any general purpose register.

What does that give us? Two things that ADD doesn't provide:

  1. the ability to perform addition with either two or three operands, and
  2. the ability to store the result in any register; not just one of the source operands.

And LEA does not alter the flags.

Examples

  • LEA EAX, [ EAX + EBX + 1234567 ] calculates EAX + EBX + 1234567 (that's three operands)
  • LEA EAX, [ EBX + ECX ] calculates EBX + ECX without overriding either with the result.
  • multiplication by constant (by two, three, five or nine), if you use it like LEA EAX, [ EBX + N * EBX ] (N can be 1,2,4,8).

Other usecase is handy in loops: the difference between LEA EAX, [ EAX + 1 ] and INC EAX is that the latter changes EFLAGS but the former does not; this preserves CMP state.

like image 30
Frank Krueger Avatar answered Oct 20 '22 09:10

Frank Krueger