Skip to content

Concepts

x86-64

x86-64 Addressing Modes

x86-64 memory operands follow the base + index*scale + displacement formula, encoded in the ModRM and SIB bytes — understanding them is essential for reading any memory access.

x86-64 memory operands use a general formula:

[base + index*scale + displacement]

All four components are optional; any combination is valid (subject to encoding constraints).

Components

ComponentDescriptionValues
baseAny 64-bit GPR (or RIP for RIP-relative)raxr15, rip
indexAny GPR except RSPraxr15 (not rsp)
scaleMultiplier for index1, 2, 4, 8
displacementSigned constant offset8-bit or 32-bit

Examples

asm
mov rax, [rbx]                  ; base only
mov rax, [rbx + 8]              ; base + disp8
mov rax, [rbx + 0x100]          ; base + disp32
mov rax, [rbx + rcx]            ; base + index (scale=1)
mov rax, [rbx + rcx*4]          ; base + index*scale
mov rax, [rbx + rcx*8 + 0x10]   ; full form
mov rax, [rip + 0x1234]         ; RIP-relative (PIC globals, x86-64 only)
mov rax, [rcx*4 + label]        ; index*scale + disp (no base — uses disp32)

Array and struct access patterns

c
int arr[100];
arr[i]       →  mov eax, [arr_base + rdi*4]     ; int = 4 bytes

struct Foo { int x; int y; long z; };
foo->z       →  mov rax, [rdi + 8]               ; offset of z = 8

RIP-relative addressing

[rip + disp32] is the standard way to reference globals and string literals in position-independent code on x86-64. The displacement is relative to the address of the next instruction (i.e. RIP after fetch).

asm
lea rdi, [rip + 0x234]   ; load address of string 0x234 bytes ahead
call printf

Reverse-engineering notes

  • [rax + rbx*8] almost always means array indexing: rax is the base pointer, rbx is the index, and 8 is sizeof(element).
  • [rdi + 0x10] accessing a struct field: 0x10 is the byte offset. Match against the struct definition to identify the field.
  • Disassemblers display [rip + X] as the resolved target address — check whether it lands in .rodata (string/constant) or .data/.bss (variable).
  • When RSP is the base, you are looking at a local variable or argument access (frame-pointer-omitted code).