Instructions
x86-64LEA (Load Effective Address)
Computes an address expression and stores the result in a register — no memory access occurs, making it a fast arithmetic shortcut.
LEA (Load Effective Address) evaluates the address expression in its memory
operand and places the computed address — not the value at that address — into
the destination register. No memory access takes place and EFLAGS are not
modified.
Syntax
lea rax, [rbx + rcx*4 + 8] ; rax = rbx + rcx*4 + 8
lea rdx, [rip + 0x1234] ; RIP-relative: loads address of a globalCommon compiler uses
| Pattern | Effective operation |
|---|---|
lea rax, [rbx + 1] | rax = rbx + 1 (add without touching flags) |
lea rax, [rbx + rbx*2] | rax = rbx * 3 |
lea rax, [rbx*4] | rax = rbx * 4 (cheaper than imul) |
lea rax, [rip + sym] | Load address of global/string (PIC code) |
Compilers often emit lea instead of add or imul precisely because it is
flag-preserving and can fold a multiply-by-scale into one instruction.
Reverse-engineering notes
- When you see
lea rdi, [rip + offset], the instruction loads a pointer (e.g. a string literal or global variable) intordi— a very common pattern beforecall printfor similar. - Decompilers usually translate
lea rax, [rbx + rbx*2]directly torax = rbx * 3, hiding the LEA entirely. - If
leaappears without an obvious multiply/add pattern, check whether the compiler is computing an array element address:lea rax, [base + idx*elem_size]. leawith a 32-bit destination (e.g.lea eax, [...]) zero-extends intorax, just like any 32-bit write in 64-bit mode.