What's the purpose of the LEA instruction?
Categories:
Understanding the LEA Instruction in x86 Assembly

Explore the purpose and common uses of the LEA (Load Effective Address) instruction in x86, x86-64, and x86-16 assembly, differentiating it from MOV.
The LEA
(Load Effective Address) instruction is a fundamental component of x86 assembly language, often misunderstood or confused with data transfer instructions like MOV
. While MOV
copies data from one location to another, LEA
calculates the memory address of its source operand and places that address into the destination operand, without actually accessing the memory location itself. This distinction makes LEA
incredibly versatile for address calculations, pointer arithmetic, and even general-purpose integer arithmetic.
What LEA Does: Address Calculation, Not Data Loading
At its core, LEA
computes the effective address of its source operand and stores this computed address in the destination register. The source operand can be a memory operand specified using various addressing modes (e.g., [base + index*scale + displacement]
). Crucially, LEA
does not dereference this address; it simply performs the arithmetic to determine what the address would be if memory were accessed. This behavior is key to its utility.
lea eax, [ebx + ecx*4 + 10h]
mov eax, [ebx + ecx*4 + 10h]
Comparison of LEA and MOV with an identical memory operand.
In the example above, LEA
will calculate the address ebx + ecx*4 + 10h
and store this numerical address into EAX
. MOV
, on the other hand, would calculate the same address, then fetch the value stored at that memory location, and place that value into EAX
. This fundamental difference is what makes LEA
a powerful tool for address manipulation.
Common Use Cases for LEA
LEA
is not just for loading addresses; its ability to perform arithmetic using the full range of x86 addressing modes makes it a highly optimized instruction for several common tasks.
LEA
as a specialized arithmetic instruction that can perform additions and multiplications (by 1, 2, 4, or 8) in a single cycle, often faster than a sequence of ADD
and MUL
instructions.flowchart TD A[Start] A --> B{Need an address or pointer?} B -->|Yes| C[Use LEA to calculate address] C --> D[Address stored in register] B -->|No| E{Need data from memory?} E -->|Yes| F[Use MOV to load data] F --> G[Data stored in register] E -->|No| H[Other operations]
Decision flow for choosing between LEA and MOV.
1. Pointer Arithmetic and Array Indexing
One of the most straightforward uses of LEA
is for calculating the address of an element within an array or structure. This is particularly useful when you need the address itself, rather than the content at that address.
; Calculate address of array[i]
lea esi, [array_base + edi*4] ; ESI now holds the address of array_base + EDI*4
; Equivalent to: esi = array_base + edi * 4
; (assuming array_base is a constant or loaded into a register)
Using LEA for array indexing to get an address.
2. Efficient General-Purpose Arithmetic
Due to its ability to perform additions and scaled multiplications (by 1, 2, 4, or 8) in a single instruction, LEA
is frequently used as a general-purpose arithmetic instruction, even when no memory address is involved. This is a common optimization technique.
; Multiply EAX by 5 (EAX * 4 + EAX)
lea eax, [eax*4 + eax]
; Add 10 to EBX
lea ebx, [ebx + 10]
; Calculate (EAX * 2) + EBX + 7
lea ecx, [eax*2 + ebx + 7]
LEA used for various arithmetic operations.
LEA
for multiplication less pronounced than in older architectures. However, for additions and small-scale multiplications, it can still be more compact and sometimes faster.3. Getting the Address of a Local Variable or Function
In position-independent code (PIC) or when working with stack-based local variables, LEA
is used to obtain their addresses. For local variables, it calculates the offset from the stack base pointer (EBP
or RBP
). For functions, it can be used to get the address of a label relative to the instruction pointer (RIP
) in x64.
; Get address of a local variable on the stack
lea eax, [ebp - 8]
; Get address of a function (x64 RIP-relative addressing)
lea rax, [function_label]
; or
lea rax, [rel function_label]
Using LEA to get addresses of stack variables and functions.
LEA
with RIP
-relative addressing in x64, ensure you understand the difference between LEA RAX, [label]
and MOV RAX, OFFSET label
. The former calculates the address at runtime, while the latter loads a fixed compile-time offset.