Z80 Registers — Main, Shadow, and Index

8-Bit CPUs — 6502/6510 & Z80

Chapter 6 · Z80 Registers — Main, Shadow, and Index

cpu8bit1-5 described the Z80's richness in the abstract — more instructions, more registers, more addressing modes. This chapter makes the register half of that claim concrete, following the exact structure cpu8bit1-3 used for the 6502, so the comparison stays direct and even-handed.

The Main Register Set — A, F, and the BC/DE/HL Pairs

Like the 6502, the Z80 has an accumulator (A) and a flags register (F) — but from there the two chips diverge sharply. Instead of two more single-purpose 8-bit registers (the 6502's X and Y), the Z80 provides six general-purpose 8-bit registers — B, C, D, E, H, L — and, crucially, they can be used either individually or combined into three genuine 16-bit register pairs: BC, DE, and HL.

This pairing is something the 6502 simply has no equivalent for at all — X and Y stay strictly 8-bit, always. The Z80's pairs make native 16-bit arithmetic possible directly:

LD  HL, $3000
LD  BC, $0005
ADD HL, BC     ; a single instruction adds two full 16-bit values

Compare that against cpu8bit1-3's own multi-byte addition example, which needed two separate 8-bit ADC instructions chained together through Carry because the 6502 has no native 16-bit arithmetic at all.

HL as a Pointer — Simpler Than Anything the 6502 Offers

HL in particular is routinely used as a direct memory pointer:

LD  HL, $3000
LD  A, (HL)     ; reads the byte AT the address held in HL — one register, one instruction

This is genuinely simpler than cpu8bit1-4's own (zp),Y — which required a pointer stored specifically in zero page, plus a separate index register, plus a two-step lookup. On the Z80, the pointer just lives directly in a 16-bit register; no zero-page indirection is needed at all.

The Shadow Register Set — A Genuinely Unique Feature

Here's where the Z80 does something neither the 6502 nor LC-3 offers any equivalent for: a complete second copy of A, F, and the BC/DE/HL pairs — the shadow (or alternate) register set, written A′, F′, B′C′D′E′H′L′. Only one set is active at any moment, and two special instructions swap between them:

  • EXX — swaps the general-purpose BC/DE/HL with their shadow counterparts, all at once, in a single instruction.
  • EX AF,AF′ — swaps A and F with their own shadow versions, separately from EXX.

The historical, documented purpose: fast interrupt handling. An interrupt routine could execute EXX to instantly gain an entirely fresh set of working registers, do whatever it needed to do, then EXX back — without ever needing to push the main registers onto the stack to protect them, and without ever needing to pop them back afterward. In practice, plenty of real Z80 programs (including software on the ZX Spectrum) simply used the shadow set as extra general-purpose storage rather than reserving it strictly for interrupts, since nothing in the hardware enforces how it's used — but the interrupt-speed use case is what motivated building it in the first place.

Index Registers — IX and IY

Two additional 16-bit registers, IX and IY, exist specifically to support indexed addressing — full treatment in cpu8bit1-7. A quick preview: LD A,(IX+5) reads the byte at whatever address IX holds, plus 5. These are exactly the registers behind two of cpu8bit1-5's own prefix bytes — IX-indexed instructions are signaled by the DD prefix, IY-indexed ones by FD. What was an abstract encoding mechanism in that chapter now has a concrete, working purpose.

Contrasted Against the 6502's Minimal Register File

6502 (cpu8bit1-3)Z80 (this chapter)
8-bit general-purpose registers3 (A, X, Y)7 in the main set (A, B, C, D, E, H, L) — doubled to 14 counting the full shadow set
Native 16-bit register pairsNoneBC, DE, HL — plus IX, IY, plus their own shadow-set counterparts
Alternate/shadow register setNone at allA complete second copy of A/F/BC/DE/HL, swapped via EXX / EX AF,AF′
Direct-register memory pointerNone — memory pointers always route through zero page (cpu8bit1-4)HL holds a pointer directly, no zero-page step required
Two threads to pick back up later
cpu8bit1-7 covers IX/IY-based addressing in full, building directly on this chapter's own preview. And cpu8bit1-9 revisits the shadow register set's real interrupt-handling payoff in depth — directly extending assembly1-8's own polling-vs-interrupts preview into a concrete hardware mechanism LC-3 never had access to at all.
All this register capability isn't free — and it's all-or-nothing per group
Every register in this chapter is part of the reason the Z80 needed roughly 8,500 transistors against the 6502's own ~3,500, per cpu8bit1-5's own comparison table — richness in registers is a direct, real silicon cost, the same way minimalism was a direct silicon saving for the 6502. It's also worth noting a real hardware constraint: EXX and EX AF,AF′ swap their entire register group at once — there's no way to selectively swap just one register out of BC/DE/HL while leaving the others in place.

Hands-On Exercises

Exercise 1

Using this chapter's own HL example and cpu8bit1-4's own (zp),Y explanation, explain specifically why dereferencing a pointer through HL is a simpler operation than the 6502's own indirect-indexed addressing — name what step the 6502 needs that the Z80 doesn't.

📄 View solution
Exercise 2

Explain the real, historical purpose of the Z80's shadow register set, and explain specifically why neither the 6502 nor LC-3 (assembly1-8's own TRAP-based I/O) has anything comparable to offer for the same problem.

📄 View solution
Exercise 3

Using this chapter's own compare table and cpu8bit1-5's transistor-count numbers, explain why the Z80 having roughly 14 total 8-bit-equivalent registers (counting both the main and shadow sets) against the 6502's 3 is consistent with — not a coincidence alongside — the two chips' own transistor budgets.

📄 View solution

Chapter 6 Quick Reference

  • Main set — A, F, and six general-purpose registers (B, C, D, E, H, L), individually 8-bit or paired into 16-bit BC/DE/HL
  • BC/DE/HL enable native 16-bit arithmetic (e.g. ADD HL,BC) — something the 6502 can only do by hand-chaining 8-bit ADC through Carry
  • HL as a pointerLD A,(HL) dereferences directly, no zero-page indirection needed, unlike the 6502's own (zp),Y
  • Shadow set — a full second copy of A/F/BC/DE/HL, swapped via EXX / EX AF,AF′, built for fast interrupt handling — no 6502 or LC-3 equivalent at all
  • IX, IY — dedicated 16-bit index registers behind the DD/FD prefix bytes from cpu8bit1-5, full addressing coverage in cpu8bit1-7
  • EXX/EX AF,AF′ swap their entire register group at once — no selective single-register swap is possible
  • This register-level richness is a direct, real contributor to the Z80's own ~8,500-transistor budget from cpu8bit1-5