Below are addressing modes (immediate, register, memory) on the examples of the mov
assembly instruction. Here we use movl
("move long") for a 32-bit word.
Note: cannot move memory-to-memory, need two instructions.
movl | Src | Dest | Src, Dest | C version |
---|---|---|---|---|
Imm | Reg | movl $0x4,%eax | x = 0x4; | |
Mem | movl $-5,(%eax) | *px = -5; | ||
Reg | Reg | movl %eax,%edx | x = y; | |
Mem | movl %eax,(%edx) | *px = y; | ||
Mem | Reg | movl (%eax),%edx | y = *px; |
Also, the most general form of memory access is:
D(Rb, Ri, S)
That corresponds to the following memory address calculation:
Mem[Reg[Rb] + S * Reg[Ri] + D]
Where:
D
: Constant "displacement" (offset), 1, 2, or 4 bytesRb
: Base register: Any of the 8/16 integer registersRi
: Index register: Any, except for%esp
/%rsp
S
: Scale: 1, 2, 4, 8 (numbers are to support arrays of values of these sizes)
Besides, special cases can use any combination of D
, Rb
, Ri
, and S
:
(Rb, Ri) Mem[Reg[Rb] + Reg[Ri]]
D(Rb, Ri) Mem[Reg[Rb] + Reg[Ri] + D]
(Rb, Ri, S) Mem[Reg[Rb] + S * Reg[Ri]]
Examples:
- Parameters access on the stack:
movl 8(%ebp), %eax ; parameter with offset 8 from the base pointer
movl 12(%ebp), %edx ; parameter with offset 12 from the base pointer
- Address computation instruction:
leal Src, Dest
, "load effective address", whereSrc
is address mode expression. The result is stored in theDest
.
leal (%edx, %ecx, 4), %eax
The leal
can be used for:
- Computing addresses without a memory reference. E.g. translation of
p = &x[i];
- Computing arithmetic expressions of the form
x + k * i
, wherek
is 1, 2, 4, or 8.