What does the LEA instruction do and how is it different from MOV?
LEA (Load Effective Address) computes an address and stores the address itself in a register — it never touches memory, unlike MOV which dereferences.
* mov dereferences — it loads the value at the address; lea loads the address itself, touches no memory and leaves the flags alone. *
This is the subtlest instruction for beginners: the parentheses in lea (%rax,%rbx,4), %rcx look like a memory access, but LEA just evaluates the address expression and keeps the number.
mov (%rax,%rbx,4), %rcx # load the VALUE at that address
lea (%rax,%rbx,4), %rcx # load the ADDRESS itself — no memory access
Because the addressing-mode hardware can compute base + index×scale + disp for free, compilers love to abuse LEA as a fast arithmetic unit:
lea (%rax,%rax,2), %rax # %rax = %rax*3
lea 1(%rax,%rax,4), %rax # %rax = %rax*5 + 1
lea (%rax,%rbx), %rcx # %rcx = %rax + %rbx
Three advantages over add/imul: it does a multiply-and-add in one instruction, it can write the result to a different register, and crucially it does not modify the condition flags — handy when you need to compute something without disturbing a pending comparison.
Go deeper:
Felix Cloutier — LEA — confirms LEA computes the address without a memory access.