Z80 Instruction Set Reference
Selected CPU instruction reference
Reference for the most common Z80 assembly instructions with T-states, bytes, and flag effects, as Zilog's Z80 CPU User Manual gives them.
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 as Zilog’s Z80 CPU User Manual gives them.
For the complete instruction set, see the Zilog manual. For the undocumented opcodes and the places where the hardware disagrees with the manual, see Sean Young’s The Undocumented Z80 Documented.
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 set or reset according to the result
- 1 = Flag always set
- 0 = Flag always reset
- — = Flag unchanged
Where the Zilog manual gives two T-state figures for a conditional instruction, the table shows them as taken/not taken.
8-Bit Load Instructions
LD r,n - Load Immediate
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, with two exceptions: LD A,I and LD A,R set S and Z from the value loaded and copy IFF2 into P/V.
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
LD rr,nn - Load 16-bit Immediate
| 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 | ● | ● | ● | ● | 0 | ● |
| ADD A,n | 2 | 7 | ● | ● | ● | ● | 0 | ● |
| ADD A,(HL) | 1 | 7 | ● | ● | ● | ● | 0 | ● |
SUB r / SUB n - Subtract
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|---|---|---|---|---|---|---|---|
| SUB B | 1 | 4 | ● | ● | ● | ● | 1 | ● |
| SUB n | 2 | 7 | ● | ● | ● | ● | 1 | ● |
INC r / DEC r - Increment/Decrement
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|---|---|---|---|---|---|---|---|
| INC A | 1 | 4 | ● | ● | ● | ● | 0 | — |
| DEC A | 1 | 4 | ● | ● | ● | ● | 1 | — |
Note: The carry flag is not affected by 8-bit INC/DEC, so a loop counter can be decremented in the middle of a multi-byte add without losing the carry.
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 | — | — | ● | — | 0 | ● |
| ADD HL,DE | 1 | 11 | — | — | ● | — | 0 | ● |
| ADD HL,HL | 1 | 11 | — | — | ● | — | 0 | ● |
| ADD HL,SP | 1 | 11 | — | — | ● | — | 0 | ● |
ADD HL,rr leaves S, Z and P/V alone, so it cannot be followed directly by a JP Z or JP P test on the sum. The index registers have their own forms — ADD IX,pp and ADD IY,rr (2 bytes, 15 T-states) — and the ED-prefixed ADC HL,rr and SBC HL,rr (2 bytes, 15 T-states) do set S, Z and P/V, which is why a 16-bit compare is usually written OR A / SBC HL,DE.
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, so DEC BC / JR NZ,loop does not work — test the pair with LD A,B / OR C first.
Logical Instructions
AND r / AND n - Logical AND
| Instruction | Bytes | T-states | S | Z | H | P/V | N | C |
|---|---|---|---|---|---|---|---|---|
| AND B | 1 | 4 | ● | ● | 1 | ● | 0 | 0 |
| AND n | 2 | 7 | ● | ● | 1 | ● | 0 | 0 |
AND sets H; OR and XOR reset it. P/V holds the parity of the result for all three.
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 Z from A and clears carry, 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: Clears A in one byte and 4 T-states, against two bytes and 7 for LD A,0. Unlike LD, it also sets Z and clears carry, so use LD A,0 when the flags must survive.
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,C affected; N set |
| CP n | 2 | 7 | S,Z,H,P/V,C affected; N set |
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: the displacement byte is −128 to +127 counted from the address after the two-byte instruction, which Zilog states as “a total displacement of +129 to –126 from the jump relative op code address”. The assembler does the adjustment. JR has only four conditions — Z, NZ, C, NC — where JP also has PE, PO, P and M.
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 |
Same range as JR. DJNZ does not touch the flags, so a carry from the loop body survives to the next iteration.
Call and Return Instructions
CALL nn - Unconditional Call
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| CALL nn | 3 | 17 | None affected |
| CALL cc,nn | 3 | 17/10 | 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 |
| PUSH IX | 2 | 15 | None affected |
POP rr - Pop from Stack
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| POP BC | 1 | 10 | None affected |
| POP AF | 1 | 10 | All flags loaded from stack |
| POP IX | 2 | 14 | None affected |
I/O Instructions
IN A,(n) - Input from Port
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| IN A,(n) | 2 | 11 | None affected |
A goes to the top half of the address bus, n to the bottom half — so IN A,($FE) on a Spectrum reads the keyboard half-row selected by whatever A held.
OUT (n),A - Output to Port
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| OUT (n),A | 2 | 11 | None affected |
IN r,(C) - Input using BC
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| IN A,(C) | 2 | 12 | S,Z,P/V affected; H,N reset |
| OUT (C),r | 2 | 12 | None affected |
The whole of BC goes onto the address bus, which is how Spectrum code addresses a specific half-row (LD BC,$DFFE / IN A,(C)) or the 128K’s paging and sound ports. See ZX Spectrum Hardware Ports.
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 |
The A-only forms leave S, Z and P/V alone; the CB-prefix forms set them from the result.
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: The CB-prefix slot between SRA and SRL is the undocumented SLL (sometimes written SL1). Young: “It works like SLA, for one exception: it sets bit 0 (SLA resets it).” It is not in the Zilog manual, and not every assembler accepts the mnemonic.
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 carries a second set of registers — AF', BC', DE' and HL' — and, in Zilog’s words, “the contents of main and alternate registers can be completely exchanged by executing only two instructions, EX and EXX”.
| 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 puts the whole main set out of harm’s way in 8 T-states and the same pair brings it back. PUSH AF / PUSH BC / PUSH DE / PUSH HL costs 44 T-states and the matching POPs 40. The saving only holds if nothing else in the program uses the alternate set — the Spectrum’s own ROM does, which is one reason games take over the interrupt entirely (see below).
Block Instructions
LDIR - Load, Increment, Repeat
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| LDIR | 2 | 21/16 | H,N reset; P/V reset on completion; S,Z,C unchanged |
Operation: Copy byte from (HL) to (DE), increment HL and DE, decrement BC. Repeat until BC = 0. 21 T-states per byte while repeating, 16 for the final byte. LDDR does the same downwards; LDI/LDD do one byte and stop.
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 |
“When a software HALT instruction is executed, the CPU executes NOPs until an interrupt is received” — either an NMI or, with interrupts enabled, a maskable one. On a Spectrum with interrupts enabled, HALT is the one-byte way to wait for the next frame.
DI / EI - Disable/Enable Interrupts
| Instruction | Bytes | T-states | Flags |
|---|---|---|---|
| DI | 1 | 4 | None affected |
| EI | 1 | 4 | None affected |
EI takes effect one instruction late: “any pending interrupt request is not accepted until after the instruction following EI is executed. This single instruction delay is necessary when the next instruction is a return instruction.” So EI / RET (or EI / RETI) returns before the next interrupt can arrive. NMI is unmaskable — DI does not block it.
Interrupt Modes
The Z80 supports three interrupt modes selected by the IM instruction. After a reset the CPU is in mode 0.
| Mode | Sets via | Behaviour | T-states (interrupt entry) |
|---|---|---|---|
| IM 0 | IM 0 (ED 46) |
The interrupting device puts an instruction on the bus during the acknowledge cycle and the CPU executes it — “often this response is a restart instruction”. | 13 for an RST |
| IM 1 | IM 1 (ED 56) |
CPU pushes PC and restarts at $0038, whatever is on the bus. The Spectrum ROM selects this. |
13 |
| IM 2 | IM 2 (ED 5E) |
CPU forms an address from I (high byte) and the byte on the data bus (low byte), reads a 16-bit address from there, and calls it. | 19 |
Zilog says the low byte’s bottom bit “must be a 0”, giving a table of 128 two-byte entries. Young tested it and found the byte is used as-is: the address is I × 256 + bus byte, unmasked.
| Instruction | Bytes | T-states | Effect |
|---|---|---|---|
| IM 0 / IM 1 / IM 2 | 2 | 8 | Select interrupt mode |
| RETI | 2 | 14 | Return from maskable interrupt; signals Z80-family peripherals that the routine is done |
| RETN | 2 | 14 | Return from NMI; copies IFF2 back into IFF1 |
NMI (non-maskable interrupt) “is always recognized at the end of the current instruction, independent of the status of the interrupt enable flip-flop, and automatically forces the CPU to restart at location 0066h.” The 48K Spectrum has nothing wired to the NMI line as standard. The ROM does hold a routine at $0066 — Logan and O’Hara note it “allows for a system reset to occur following activation of the NMI line” but “is not used as the instruction ‘JR NZ’ should have been ‘JR Z’!”. Anything that does drive the line, such as the Multiface, has to bring its own handler with it.
Interrupts on the Spectrum
The ROM’s initialisation sets I to $3F and selects IM 1. Every 20 ms an interrupt arrives, and the ROM’s MASK-INT routine at $0038 increments FRAMES, scans the keyboard, and returns with EI / RET. A program that lives with that gets a free 50 Hz clock and keyboard scan; a program that needs its own 50 Hz routine, or uses the alternate registers, switches to IM 2.
IM 2 on the Spectrum has one complication: nothing in the machine puts a chosen byte on the bus during the acknowledge cycle, so the low byte of the vector is whatever the bus is floating at — Young notes that on such systems “this value ends up being FFh” — and, with peripherals attached, it can be anything. Since the byte is not under the program’s control, and is not masked to even values, the vector table must give the same result from any of the 256 possible offsets. That is why the table is 257 bytes of one value, so that every pair of neighbouring bytes reads as the same address. The +3 manual adds where the table may safely go: keep I out of $40-$7F on the 48K to +2 (the video RAM region), and out of $C0-$FF when a contended bank is paged at $C000; “you should only vector IM 2 interrupts to between 8000h and BFFFh”.
Common Instruction Patterns
Clear A Register (fastest)
XOR A ; 4 T-states (vs LD A,0 = 7); also sets Z, clears C
Test if A is Zero
OR A ; Sets Z flag without changing A
JR Z,IsZero
Double A Register
ADD A,A ; Shift left one bit, carry gets bit 7
Delay Loop
LD B,100
Delay: DJNZ Delay ; 13 × 99 + 8 = 1295 T-states
16-bit compare
OR A ; clear carry
SBC HL,DE ; HL - DE, sets Z and C
JR C,HLless ; carry set: HL < DE
Performance Notes
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. - Prefer
JRoverJPfor size, not speed —JR eis 12T (slower thanJP nnat 10T) but only 2 bytes (vs 3). ConditionalJR cc,eis 12T taken / 7T not taken;JP cc,nnis always 10T. So in tight code where the not-taken path dominates,JR ccis faster and smaller. - Use
DJNZfor counted loops — 13/8 T-states with no separate decrement and test. - Use
EX AF,AF'+EXXfor register backup in interrupt handlers (8T total against 44T + 40T for four pushes and four pops), if nothing else uses the alternate set. OR A(1 byte) clears carry and tests A for zero without changing it.CP 0gives the same Z and C but takes 2 bytes and sets N.- Unroll loops in speed-critical code (raster effects, audio mixing, sprite blitting).