What's the purpose of the LEA instruction?
assembly, x86, x86-16, x86-64
Solution
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`.
Problem
For me, it just seems like a funky MOV. What's its purpose and when should I use it?
Related problems
- Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?
- Which 2's complement integer operations can be used without zeroing high bits in the inputs, if only the low part of the result is wanted?
- What does the colon : mean in x86 assembly GAS syntax as in %ds:(%bx)?
- NASM Assembly convert input to integer?
- Is a mov to a segmentation register slower than a mov to a general purpose register?
- What is the "EU" in x86 architecture? (calculates effective address?)
- Get linear address of FS:[0] in 32-bit protected mode / MSVC inline asm