Registers, Reimagined
x86-64 Assembly
Chapter 2 · Registers, Reimagined
assembly2-1 promised the clearest artifact of x86-64's own history would show up inside a single register's name. Here it is — sixteen general-purpose registers, eight of them carrying four historical layers of naming at once, and eight of them carrying none at all.
The 16 General-Purpose Registers
x86-64 has 16 general-purpose 64-bit registers: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, and R8–R15. That's comparable in scale to cpu8bit1-6's own Z80 total (14, counting the main and shadow sets together) — but with a real difference: all 16 of x86-64's registers are usable simultaneously, with no EXX-style swap ever required to reach half of them.
The first eight trace directly back to the original 8086 (assembly2-1's own starting point), each with a historically-loaded name still partly tied to a specific role: Accumulator, Base, Counter, Data, Source Index, Destination Index, Base Pointer, Stack Pointer. Some of those roles are still real, not just historical trivia — RCX is still the implicit loop counter the LOOP instruction (assembly2-6) automatically decrements, exactly the way its name has promised since 1978.
R8 through R15 are entirely new — added specifically for the 64-bit extension assembly2-1 credited to AMD. They have no inherited name at all, just numbers, because they never needed to carry any legacy forward.
The Sub-Register Maze — RAX/EAX/AX/AH-AL
One physical 64-bit storage location, addressable at four different widths, under four different names:
EAX ("Extended AX") was the whole register back when the 80386 was the newest chip in the lineage. AX was the whole register back in the 8086's own original 16-bit era. AH/AL go back that far too — letting even 1978-era code address just the upper or lower half of a 16-bit value. Nothing here was ever removed; every later chip just added a wider name on top of the one that came before.
The same four-level pattern applies to three more of the original eight: RBX/EBX/BX/BH-BL, RCX/ECX/CX/CH-CL, and RDX/EDX/DX/DH-DL.
EAX) automatically zeroes the upper 32 bits of the full 64-bit register. Writing to the 16-bit or 8-bit forms (AX, AH, AL) does not — everything above the bits actually written is left completely untouched. The two sub-register sizes behave differently by design, and assuming one behaves like the other is a real, easy mistake.
Historically, RSI/RDI/RBP/RSP didn't have their own H/L 8-bit forms the way AX/BX/CX/DX did — only their 16-bit SI/DI/BP/SP forms existed classically. x86-64 specifically added new 8-bit low-byte access to these — SIL, DIL, BPL, SPL — using a special encoding prefix. One more concrete instance of assembly2-1's own theme: a genuinely new capability, layered on without ever touching what already existed.
R8–R15's Own Cleaner Pattern
Because R8–R15 never had to inherit an old name, they got a uniform, modern naming scheme from day one: R8 (64-bit), R8D (32-bit, "D" for Double word), R8W (16-bit, "W" for Word), R8B (8-bit, "B" for Byte) — and the exact same pattern for R9 through R15, no exceptions, no historical quirks.
| Width | Legacy register (RAX family) | New register (R8 family) |
|---|---|---|
| 64-bit | RAX | R8 |
| 32-bit | EAX | R8D |
| 16-bit | AX | R8W |
| 8-bit | AH / AL (two separate sub-names) | R8B |
The new registers' naming is strictly more regular than the legacy ones' — a small, direct illustration that code and conventions never carrying old baggage in the first place are simply cleaner than ones that had to accumulate it.
cpu8bit1-6's own Z80 register total, x86-64's 16 always-available general-purpose registers are a genuinely more straightforward design than needing an EXX-style swap to reach half of a comparable total — one more small way this architecture's real complexity shows up in naming and history rather than in access mechanics.
Hands-On Exercises
Using this chapter's own bit diagrams, identify exactly which bits of RAX are affected by a write to AL, a write to AX, and a write to EAX, respectively.
📄 View solutionRAX currently holds 0xFFFFFFFF12345678. The instruction MOV EAX, 0 executes. Using this chapter's own warn-box, state RAX's full 64-bit value afterward, and explain why it's not 0xFFFFFFFF00000000.
Explain why R8's own sub-register naming (R8/R8D/R8W/R8B) is more regular than RAX's own (RAX/EAX/AX/AH-AL), and connect the reason directly back to assembly2-1's own "four decades of accretion" theme.
📄 View solutionChapter 2 Quick Reference
- 16 general-purpose registers, all simultaneously usable: RAX, RBX, RCX, RDX, RSI, RDI, RBP, RSP, and R8–R15
- The original 8 trace back to the 8086 and carry historically-loaded names — some (like RCX/LOOP) still have real implicit uses
- RAX → EAX → AX → AH/AL — one physical register, four historical widths, four different names
- Writing a 32-bit sub-register (EAX) zeroes the upper 32 bits of the 64-bit register; writing a 16-bit or 8-bit sub-register does not
- SIL/DIL/BPL/SPL are x86-64-only additions — new capability layered on, nothing removed
- R8–R15 use a clean, uniform R8/R8D/R8W/R8B pattern — no legacy naming to carry, because they're entirely new
- All 16 registers are always available at once — no EXX-style swap needed, unlike cpu8bit1-6's own Z80 shadow set