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
.
In this use-case LEA and MOV do the same thing. LEA is more powerful than MOV if you want to calculate an address in a more complex way.
Lets for example say you want to get the address of the n'th character in your array, and the n is stored in bx. With MOV you have to write the following two instructions:
Mov dx, offset ar
add dx, bx
With lea you can do it with just one instruction:
lea dx, [ar + bx]
Another thing to consider here: the add dx,bx
instruction will change the status flags of the CPU. The addition done inside the lea dx, [ar + bx]
instruction on the other hand does not change the flags in any way because it is not considered an arithmetic instruction.
This is sometimes helpful if you want to preserve the flags while doing some simple calculations (address calculations are very common). Storing and restoring the flag-register is doable but a slow operation.
Best Answer
LEA
means Load Effective AddressMOV
means Load ValueIn short,
LEA
loads a pointer to the item you're addressing whereas MOV loads the actual value at that address.The purpose of
LEA
is to allow one to perform a non-trivial address calculation and store the result [for later usage]Where there are just constants involved,
MOV
(through the assembler's constant calculations) can sometimes appear to overlap with the simplest cases of usage ofLEA
. Its useful if you have a multi-part calculation with multiple base addresses etc.