Memory Addressing — The Full SIB Addressing Mode
x86-64 Assembly
Chapter 4 · Memory Addressing — The Full SIB Addressing Mode
Three courses, three addressing stories: LC-3's clean base+offset, the 6502's zero-page workaround, the Z80's displacement-based indexing. x86-64 doesn't pick one — it combines the ideas behind all of them into a single addressing mode genuinely richer than anything either prior course covered, plus one capability neither ever offered at all.
The Addressing Journey So Far
| Architecture | Richest addressing mode covered | Automatic index scaling? |
|---|---|---|
| LC-3 (assembly1-3) | Base+offset — a register plus a small constant | No |
| 6502 (cpu8bit1-4) | (zp),Y — a zero-page pointer plus an index register | No |
| Z80 (cpu8bit1-7) | (IX+d) — a register plus an 8-bit displacement | No |
| x86-64 (this chapter) | Base + Index×Scale + Displacement, all in one instruction | Yes |
The Full SIB Addressing Mode
x86-64's richest memory operand computes its effective address as:
effective address = Base + (Index × Scale) + Displacement
- Base — any general-purpose register, holding a starting address, playing the same role as the Z80's own HL or the 6502's zero-page pointer.
- Index — any general-purpose register, typically an array index.
- Scale — a multiplier applied to Index, restricted to 1, 2, 4, or 8 — matching byte/word/dword/qword element sizes exactly.
- Displacement — a constant offset, the same role LC-3's PC-relative offset and the Z80's own
+ddisplacement played.
MOV RAX, [RBX + RCX*4 + 8] ; RBX = array base, RCX = index, *4 for 4-byte elements, +8 skips a header
Why This Matters — No Manual Multiply Required
On the 6502 or Z80, indexing into an array of 4-byte elements would mean multiplying the index by 4 before the address could be computed — typically two shift-left operations, or repeated addition, as a separate step every single time. x86-64's Scale performs that exact multiplication as part of the address computation itself, inside the same instruction that actually accesses memory. This is a genuinely new capability, not just a faster version of something the earlier chips already did.
cpu8bit1-7's own warn-box already flagged for the Z80's own richer-but-not-unlimited addressing modes.
Not Every Component Is Required
Base, Index, Scale, and Displacement are all optional individually — an instruction only pays for the pieces it actually uses:
MOV RAX, [RBX] ; base only — like Z80's own (HL) MOV RAX, [RBX + 8] ; base + displacement — like Z80's own (IX+d) MOV RAX, [RBX + RCX] ; base + index, scale defaults to 1 MOV RAX, [RBX + RCX*4 + 8] ; all four components together
RIP-Relative Addressing — PC-Relative, Returned
x86-64 also added a genuinely new mode: [RIP + offset], computing an address relative to the current instruction pointer. This is conceptually the exact same idea as assembly1-3's own LC-3 PC-relative LD — but for a completely different, distinctly modern reason. LC-3 needed PC-relative addressing because a 16-bit instruction had no room for a full address at all. x86-64 doesn't have that bit-budget problem (assembly2-1's own variable-length instructions solve it) — RIP-relative addressing exists instead to support position-independent code: a program whose data references stay correct no matter where in memory the operating system actually loads it, a real security and shared-library requirement neither LC-3 nor the 6502/Z80 ever had to think about. The same underlying technique, reinvented decades later to solve an unrelated problem.
assembly2-12's own capstone leans directly on this chapter's full SIB mode — walking a real array using base+index×scale addressing in a single instruction is exactly the kind of concrete richness neither assembly1-10 nor cpu8bit1-12's own capstones had available to them.
Hands-On Exercises
Given RBX (base) = 0x1000, RCX (index) = 5, a scale of 8, and a displacement of 16, compute the effective address of [RBX + RCX*8 + 16], showing your work.
Explain specifically what extra instruction(s) a 6502 or Z80 program would need, that an equivalent x86-64 program using Scale wouldn't, when indexing into an array of 8-byte elements.
📄 View solutionExplain what RIP-relative addressing and LC-3's own PC-relative addressing (assembly1-3) have in common mechanically, and explain why each architecture actually needed it for a genuinely different reason.
📄 View solutionChapter 4 Quick Reference
- Effective address = Base + (Index × Scale) + Displacement — the richest single addressing mode across this whole three-course arc
- Scale must be 1, 2, 4, or 8 — matching byte/word/dword/qword element sizes exactly; nothing else is directly supported
- Scale performs index-multiplication as part of the address computation — the genuinely new capability neither the 6502 nor the Z80 offered
- All four components (Base/Index/Scale/Displacement) are individually optional — an instruction only pays for what it uses
- RIP-relative addressing — PC-relative addressing's conceptual return, now for position-independent code rather than a fixed-width instruction's bit budget
- assembly2-12's capstone directly exercises SIB addressing for real array access