Aprelius logo
uptime: 00:00:00
Assembly

MOV and LEA Instructions

Differences

MOV (move or rather copy) can dereference memory address, so using [brackets] it can go to memory address rather than just copy it.

LEA = Load Effective Address. LEA does not access memory — it calculates what the address would be but never actually goes there.

InstructionMemory Access?Use Case
mov eax, ebxNoCopy register to register
mov eax, [ebx]YesLoad value from memory
lea eax, [ebx]NoCopy register (same as mov eax, ebx)
lea eax, [ebx + 8]NoCalculate address/do arithmetic
mov eax, [ebx + 8]YesLoad value from calculated address

Examples

asm
# MOV
mov eax, ebx        ; copies the value held in ebx straight into eax (no mem lookup)
mov eax, 42         ; put value 42 into eax, so 42 is embedded into the instruction
mov eax, [ebx]      ; treat ebx as a memory address, similar to *ptr in C
mov eax, [ebx + 8]  ; Go to address (ebx + 8), fetch value there
asm
# LEA
lea eax, [ebx]      ; Just copies ebx value to eax (no memory access), == mov eax, ebx
lea eax, ebx        ; INVALID! LEA always requires brackets
# Where LEA becomes powerful: address arithmetic
mov ebx, 100
lea ebx, [ebx + 12] ; ebx = 112 (calculated 100 + 12, stored back)

x86 addressing mode format

text
[base_register + index_register * scale + displacement]
  • scale can ONLY be: 1, 2, 4, or 8
  • base_register and index_register can be the same register
  • displacement is a constant number
asm
# ebx = 100, ecx = 5

lea eax, [ebx + ecx*4 + 7]    ; eax = 100 + 5*4 + 7 = 127

LEA as a multiplication trick

Compilers use LEA for fast multiplication because it's a single instruction:

asm
lea eax, [eax + eax*2]    ; eax = eax + eax*2 = 3*eax (if eax=10, result is 30)
lea eax, [eax*4]          ; multiply by 4
lea eax, [eax*2 + 6]      ; multiply by 2, add 6
lea eax, [eax + eax]      ; multiply by 2 (1 + 1)
lea eax, [eax + eax*8]    ; multiply by 9 (1 + 8)

IMPORTANT! Cannot do with a single LEA: multiply by 6, 7, 10, 11, etc. — those need multiple instructions.