Selected reference for Z80 microprocessor instructions as used in the ZX Spectrum (and any other Z80 system — MSX, Amstrad CPC, Master System, CP/M machines). Covers the most common instruction families: 8/16-bit loads, arithmetic, logical, jumps, calls, stack, I/O, block moves, and shifts/rotates/bit ops. Each entry lists T-states (clock cycles), byte count, and flag effects.
For the complete instruction set including every undocumented opcode, see Zilog's reference manual or the Z80 documentation at z80.info.
Reading This Reference
Notation
- n = 8-bit immediate value (0-255)
- nn = 16-bit immediate value (0-65535)
- d = 8-bit signed displacement (-128 to +127)
- r = 8-bit register (A, B, C, D, E, H, L)
- rr = 16-bit register pair (BC, DE, HL, SP)
- (addr) = memory at address
- $ = current address (in expressions)
Flag Notation
- S = Sign flag (bit 7 of result)
- Z = Zero flag (result is zero)
- H = Half-carry flag (carry from bit 3 to 4)
- P/V = Parity/Overflow flag
- N = Add/Subtract flag (for BCD)
- C = Carry flag
- ● = Flag affected
- ○ = Flag reset
- — = Flag unchanged
- ? = Flag undefined
8-Bit Load Instructions
Load 8-bit value into register.
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|
| LD A,n | 2 | 7 | — | — | — | — | — | — |
| LD B,n | 2 | 7 | — | — | — | — | — | — |
| LD C,n | 2 | 7 | — | — | — | — | — | — |
| LD D,n | 2 | 7 | — | — | — | — | — | — |
| LD E,n | 2 | 7 | — | — | — | — | — | — |
| LD H,n | 2 | 7 | — | — | — | — | — | — |
| LD L,n | 2 | 7 | — | — | — | — | — | — |
Example:
LD A,42 ; A = 42
LD B,0 ; B = 0
LD H,$40 ; H = $40 (64 decimal)
Note: LD instructions do not affect flags.
LD r,r' - Load Register to Register
| Instruction | Bytes | T-states | Flags |
|---|
| LD A,B | 1 | 4 | None affected |
| LD B,C | 1 | 4 | None affected |
| LD H,L | 1 | 4 | None affected |
All 49 combinations: A,B,C,D,E,H,L can be copied to/from each other.
LD r,(HL) - Load from Memory
Load register from memory address in HL.
| Instruction | Bytes | T-states | Flags |
|---|
| LD A,(HL) | 1 | 7 | None affected |
| LD B,(HL) | 1 | 7 | None affected |
| LD C,(HL) | 1 | 7 | None affected |
LD (HL),r - Store to Memory
Store register to memory address in HL.
| Instruction | Bytes | T-states | Flags |
|---|
| LD (HL),A | 1 | 7 | None affected |
| LD (HL),B | 1 | 7 | None affected |
| LD (HL),n | 2 | 10 | None affected |
16-Bit Load Instructions
| Instruction | Bytes | T-states | Flags |
|---|
| LD BC,nn | 3 | 10 | None affected |
| LD DE,nn | 3 | 10 | None affected |
| LD HL,nn | 3 | 10 | None affected |
| LD SP,nn | 3 | 10 | None affected |
| LD IX,nn | 4 | 14 | None affected |
| LD IY,nn | 4 | 14 | None affected |
Arithmetic Instructions
ADD A,r / ADD A,n - Add
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|
| ADD A,B | 1 | 4 | ● | ● | ● | ● | ○ | ● |
| ADD A,n | 2 | 7 | ● | ● | ● | ● | ○ | ● |
| ADD A,(HL) | 1 | 7 | ● | ● | ● | ● | ○ | ● |
SUB r / SUB n - Subtract
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|
| SUB B | 1 | 4 | ● | ● | ● | ● | ● | ● |
| SUB n | 2 | 7 | ● | ● | ● | ● | ● | ● |
INC r / DEC r - Increment/Decrement
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|
| INC A | 1 | 4 | ● | ● | ● | ● | ○ | — |
| DEC A | 1 | 4 | ● | ● | ● | ● | ● | — |
Note: Carry flag is NOT affected by INC/DEC!
16-Bit Arithmetic
ADD HL,rr - 16-bit Add
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|
| ADD HL,BC | 1 | 11 | — | — | ● | — | ○ | ● |
| ADD HL,DE | 1 | 11 | — | — | ● | — | ○ | ● |
| ADD HL,HL | 1 | 11 | — | — | ● | — | ○ | ● |
| ADD HL,SP | 1 | 11 | — | — | ● | — | ○ | ● |
Important: Only HL can be the destination for 16-bit ADD!
INC rr / DEC rr - 16-bit Increment/Decrement
| Instruction | Bytes | T-states | Flags |
|---|
| INC BC | 1 | 6 | None affected |
| DEC HL | 1 | 6 | None affected |
Important: 16-bit INC/DEC do NOT affect any flags!
Logical Instructions
AND r / AND n - Logical AND
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|
| AND B | 1 | 4 | ● | ● | ● | ● | ○ | ○ |
| AND n | 2 | 7 | ● | ● | ● | ● | ○ | ○ |
OR r / OR n - Logical OR
| Instruction | Bytes | T-states | Flags |
|---|
| OR B | 1 | 4 | S,Z,P/V affected, H,N,C reset |
| OR n | 2 | 7 | S,Z,P/V affected, H,N,C reset |
OR A idiom: Sets zero flag without changing A.
XOR r / XOR n - Logical XOR
| Instruction | Bytes | T-states | Flags |
|---|
| XOR B | 1 | 4 | S,Z,P/V affected, H,N,C reset |
| XOR n | 2 | 7 | S,Z,P/V affected, H,N,C reset |
XOR A idiom: Fastest way to set A to zero (4 T-states vs LD A,0 = 7 T-states).
CP r / CP n - Compare
Like SUB but doesn't store result (only sets flags).
| Instruction | Bytes | T-states | Flags |
|---|
| CP B | 1 | 4 | S,Z,H,P/V,N,C affected |
| CP n | 2 | 7 | S,Z,H,P/V,N,C affected |
Jump Instructions
JP nn - Unconditional Jump
| Instruction | Bytes | T-states | Flags |
|---|
| JP nn | 3 | 10 | None affected |
| JP (HL) | 1 | 4 | None affected |
JP cc,nn - Conditional Jump
| Condition | Meaning | Instruction | Bytes | T-states |
|---|
| Z | Zero | JP Z,nn | 3 | 10 |
| NZ | Not zero | JP NZ,nn | 3 | 10 |
| C | Carry | JP C,nn | 3 | 10 |
| NC | No carry | JP NC,nn | 3 | 10 |
JR d - Relative Jump
| Instruction | Bytes | T-states | Flags |
|---|
| JR d | 2 | 12 | None affected |
| JR Z,d | 2 | 12/7 | None affected |
| JR NZ,d | 2 | 12/7 | None affected |
Range: -126 to +129 bytes from current position.
DJNZ d - Decrement and Jump if Not Zero
Special loop instruction. Decrements B and jumps if B ≠ 0.
| Instruction | Bytes | T-states | Flags |
|---|
| DJNZ d | 2 | 13/8 | None affected |
Perfect for counted loops!
Call and Return Instructions
CALL nn - Unconditional Call
| Instruction | Bytes | T-states | Flags |
|---|
| CALL nn | 3 | 17 | None affected |
RET - Return from Subroutine
| Instruction | Bytes | T-states | Flags |
|---|
| RET | 1 | 10 | None affected |
| RET Z | 1 | 11/5 | None affected |
| RET NZ | 1 | 11/5 | None affected |
Stack Instructions
PUSH rr - Push to Stack
| Instruction | Bytes | T-states | Flags |
|---|
| PUSH BC | 1 | 11 | None affected |
| PUSH DE | 1 | 11 | None affected |
| PUSH HL | 1 | 11 | None affected |
| PUSH AF | 1 | 11 | None affected |
POP rr - Pop from Stack
| Instruction | Bytes | T-states | Flags |
|---|
| POP BC | 1 | 10 | None affected (except POP AF) |
| POP AF | 1 | 10 | All flags loaded from stack |
I/O Instructions
| Instruction | Bytes | T-states | Flags |
|---|
| IN A,(n) | 2 | 11 | None affected |
OUT (n),A - Output to Port
| Instruction | Bytes | T-states | Flags |
|---|
| OUT (n),A | 2 | 11 | None affected |
| Instruction | Bytes | T-states | Flags |
|---|
| IN A,(C) | 2 | 12 | S,Z,P/V affected, H,N reset |
Rotate and Shift Instructions
The "fast" rotates act on A only and are 1-byte / 4 T-states. The general rotates and shifts (CB-prefix) work on any 8-bit register or (HL) and are 2-byte / 8 T-states (for register) or 2-byte / 15 T-states (for (HL)). All set the carry from the bit shifted out.
Fast (A-only) rotates
| Instruction | Bytes | T-states | Description |
|---|
| RLCA | 1 | 4 | Rotate A left circular (bit 7 → C and → bit 0) |
| RLA | 1 | 4 | Rotate A left through carry |
| RRCA | 1 | 4 | Rotate A right circular |
| RRA | 1 | 4 | Rotate A right through carry |
General rotates and shifts (CB-prefix)
| Instruction | Bytes | T-states (reg / (HL)) | Description |
|---|
| RLC r | 2 | 8 / 15 | Rotate left circular |
| RL r | 2 | 8 / 15 | Rotate left through carry |
| RRC r | 2 | 8 / 15 | Rotate right circular |
| RR r | 2 | 8 / 15 | Rotate right through carry |
| SLA r | 2 | 8 / 15 | Shift left arithmetic (bit 0 ← 0) |
| SRA r | 2 | 8 / 15 | Shift right arithmetic (bit 7 preserved — sign extend) |
| SRL r | 2 | 8 / 15 | Shift right logical (bit 7 ← 0) |
Note: No SLL in documented Z80; it's an undocumented SL1 that shifts in a 1.
Bit Operations (CB-prefix)
| Instruction | Bytes | T-states (reg / (HL)) | Description |
|---|
| BIT b,r | 2 | 8 / 12 | Test bit b of register; sets Z if bit clear |
| SET b,r | 2 | 8 / 15 | Set bit b of register to 1 |
| RES b,r | 2 | 8 / 15 | Reset bit b of register to 0 |
BIT is a non-destructive test — flags update but the register is unchanged. SET and RES modify in place.
Exchange Instructions
The Z80's defining feature is its alternate register set — a shadow BC'/DE'/HL'/AF' swappable in one cycle. This is what makes interrupt handlers cheap: swap to the shadow set, do work, swap back.
| Instruction | Bytes | T-states | Description |
|---|
| EX DE,HL | 1 | 4 | Swap DE ↔ HL |
| EX AF,AF' | 1 | 4 | Swap AF ↔ AF' (alternate flags) |
| EXX | 1 | 4 | Swap BC/DE/HL ↔ BC'/DE'/HL' all at once |
| EX (SP),HL | 1 | 19 | Swap HL with the word at top of stack |
Interrupt handler idiom: EX AF,AF' + EXX saves the entire register state in 8 T-states; the inverse pair restores it. Compare ~50 T-states for PUSH AF / PUSH BC / PUSH DE / PUSH HL and the matching POPs.
Block Instructions
LDIR - Load, Increment, Repeat
| Instruction | Bytes | T-states | Flags |
|---|
| LDIR | 2 | 21/16 | H,P/V,N reset |
Operation: Copy byte from (HL) to (DE), increment HL and DE, decrement BC. Repeat until BC = 0.
Example:
; Copy 6144 bytes from $8000 to $4000
LD HL,$8000 ; Source
LD DE,$4000 ; Destination
LD BC,6144 ; Count
LDIR ; Copy all bytes
Miscellaneous Instructions
NOP - No Operation
| Instruction | Bytes | T-states | Flags |
|---|
| NOP | 1 | 4 | None affected |
HALT - Halt CPU
| Instruction | Bytes | T-states | Flags |
|---|
| HALT | 1 | 4 | None affected |
DI / EI - Disable/Enable Interrupts
| Instruction | Bytes | T-states | Flags |
|---|
| DI | 1 | 4 | None affected |
| EI | 1 | 4 | None affected |
EI is special: interrupts remain disabled for one instruction after EI to allow EI / RETI patterns. NMI is unmaskable — DI does not block it.
Interrupt Modes
The Z80 supports three interrupt modes selected by the IM instruction:
| Mode | Sets via | Behaviour | T-states (interrupt entry) |
|---|
| IM 0 | IM 0 (ED 46) | External device places opcode on bus during INTA cycle; CPU executes it. Typically RST p (1 byte). | ~13 (for RST-form) |
| IM 1 | IM 1 (ED 56) | CPU pushes PC, jumps to fixed $0038. Used by ZX Spectrum. | 13 |
| IM 2 | IM 2 (ED 5E) | Device places vector on bus; CPU forms address (I shifted left 8) OR (vector AND $FE), reads target from there. | 19 |
The Spectrum's IM 1 vector at $0038 is in ROM and runs the keyboard scan + frame counter; custom games install their own handler by setting up IM 2 with a vector table.
| Instruction | Bytes | T-states | Effect |
|---|
| IM 0 / IM 1 / IM 2 | 2 | 8 | Select interrupt mode |
| RETI | 2 | 14 | Return from maskable interrupt; signals to peripherals |
| RETN | 2 | 14 | Return from NMI; restores IFF1 from IFF2 |
NMI (non-maskable interrupt) vectors to $0066 and is unmaskable. The Spectrum routes the keyboard RESET button through NMI (sometimes — varies per model).
Common Instruction Patterns
Clear A Register (fastest)
XOR A ; 4 T-states (vs LD A,0 = 7)
Test if A is Zero
OR A ; Sets Z flag without changing A
JR Z,IsZero
Double A Register
ADD A,A ; Faster than multiplying
Delay Loop
LD B,100
Delay: DJNZ Delay ; 13 × 99 + 8 = 1295 T-states
Fastest instructions:
- Register operations: 4 T-states
- XOR A (clear A): 4 T-states
- INC/DEC register: 4 T-states
Optimisation tips:
- Use register operations over memory.
- Use HL instead of IX/IY for indexed access —
LD r,(HL) is 7 T-states, LD r,(IX+d) is 19 T-states (~2.7× slower).
- Prefer
JR over JP for size, not speed — JR e is 12T (slower than JP nn at 10T) but only 2 bytes (vs 3). Conditional JR cc,e is 12T taken / 7T not taken; JP cc,nn is always 10T. So in tight code where the not-taken path dominates, JR cc is faster and smaller.
- Use
DJNZ for counted loops — 13/8 T-states with no fiddling with B by hand.
- Use
EX AF,AF' + EXX for fast register backup in interrupt handlers (8T total vs ~50T for the equivalent push/pop sequence).
OR A (1 byte) clears carry without changing A. CP 0 does the same flag-wise but is 2 bytes — prefer OR A for both register-test and clear-carry idioms.
- Unroll loops in speed-critical code (raster effects, audio mixing, sprite blitting).
See also