Skip to content
Techniques & Technology

Z80 Instruction Set Reference

Selected CPU instruction reference

Reference for the most common Z80 assembly instructions with T-states, bytes, and flag effects.

sinclair-zx-spectrum z80instructionsassemblyreferenceopcodes

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

LD r,n - Load Immediate

Load 8-bit value into register.

InstructionBytesT-statesSZHP/VNC
LD A,n27
LD B,n27
LD C,n27
LD D,n27
LD E,n27
LD H,n27
LD L,n27

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

InstructionBytesT-statesFlags
LD A,B14None affected
LD B,C14None affected
LD H,L14None 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.

InstructionBytesT-statesFlags
LD A,(HL)17None affected
LD B,(HL)17None affected
LD C,(HL)17None affected

LD (HL),r - Store to Memory

Store register to memory address in HL.

InstructionBytesT-statesFlags
LD (HL),A17None affected
LD (HL),B17None affected
LD (HL),n210None affected

16-Bit Load Instructions

LD rr,nn - Load 16-bit Immediate

InstructionBytesT-statesFlags
LD BC,nn310None affected
LD DE,nn310None affected
LD HL,nn310None affected
LD SP,nn310None affected
LD IX,nn414None affected
LD IY,nn414None affected

Arithmetic Instructions

ADD A,r / ADD A,n - Add

InstructionBytesT-statesSZHP/VNC
ADD A,B14
ADD A,n27
ADD A,(HL)17

SUB r / SUB n - Subtract

InstructionBytesT-statesSZHP/VNC
SUB B14
SUB n27

INC r / DEC r - Increment/Decrement

InstructionBytesT-statesSZHP/VNC
INC A14
DEC A14

Note: Carry flag is NOT affected by INC/DEC!


16-Bit Arithmetic

ADD HL,rr - 16-bit Add

InstructionBytesT-statesSZHP/VNC
ADD HL,BC111
ADD HL,DE111
ADD HL,HL111
ADD HL,SP111

Important: Only HL can be the destination for 16-bit ADD!

INC rr / DEC rr - 16-bit Increment/Decrement

InstructionBytesT-statesFlags
INC BC16None affected
DEC HL16None affected

Important: 16-bit INC/DEC do NOT affect any flags!


Logical Instructions

AND r / AND n - Logical AND

InstructionBytesT-statesSZHP/VNC
AND B14
AND n27

OR r / OR n - Logical OR

InstructionBytesT-statesFlags
OR B14S,Z,P/V affected, H,N,C reset
OR n27S,Z,P/V affected, H,N,C reset

OR A idiom: Sets zero flag without changing A.

XOR r / XOR n - Logical XOR

InstructionBytesT-statesFlags
XOR B14S,Z,P/V affected, H,N,C reset
XOR n27S,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).

InstructionBytesT-statesFlags
CP B14S,Z,H,P/V,N,C affected
CP n27S,Z,H,P/V,N,C affected

Jump Instructions

JP nn - Unconditional Jump

InstructionBytesT-statesFlags
JP nn310None affected
JP (HL)14None affected

JP cc,nn - Conditional Jump

ConditionMeaningInstructionBytesT-states
ZZeroJP Z,nn310
NZNot zeroJP NZ,nn310
CCarryJP C,nn310
NCNo carryJP NC,nn310

JR d - Relative Jump

InstructionBytesT-statesFlags
JR d212None affected
JR Z,d212/7None affected
JR NZ,d212/7None 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.

InstructionBytesT-statesFlags
DJNZ d213/8None affected

Perfect for counted loops!


Call and Return Instructions

CALL nn - Unconditional Call

InstructionBytesT-statesFlags
CALL nn317None affected

RET - Return from Subroutine

InstructionBytesT-statesFlags
RET110None affected
RET Z111/5None affected
RET NZ111/5None affected

Stack Instructions

PUSH rr - Push to Stack

InstructionBytesT-statesFlags
PUSH BC111None affected
PUSH DE111None affected
PUSH HL111None affected
PUSH AF111None affected

POP rr - Pop from Stack

InstructionBytesT-statesFlags
POP BC110None affected (except POP AF)
POP AF110All flags loaded from stack

I/O Instructions

IN A,(n) - Input from Port

InstructionBytesT-statesFlags
IN A,(n)211None affected

OUT (n),A - Output to Port

InstructionBytesT-statesFlags
OUT (n),A211None affected

IN r,(C) - Input using BC

InstructionBytesT-statesFlags
IN A,(C)212S,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

InstructionBytesT-statesDescription
RLCA14Rotate A left circular (bit 7 → C and → bit 0)
RLA14Rotate A left through carry
RRCA14Rotate A right circular
RRA14Rotate A right through carry

General rotates and shifts (CB-prefix)

InstructionBytesT-states (reg / (HL))Description
RLC r28 / 15Rotate left circular
RL r28 / 15Rotate left through carry
RRC r28 / 15Rotate right circular
RR r28 / 15Rotate right through carry
SLA r28 / 15Shift left arithmetic (bit 0 ← 0)
SRA r28 / 15Shift right arithmetic (bit 7 preserved — sign extend)
SRL r28 / 15Shift 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)

InstructionBytesT-states (reg / (HL))Description
BIT b,r28 / 12Test bit b of register; sets Z if bit clear
SET b,r28 / 15Set bit b of register to 1
RES b,r28 / 15Reset 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.

InstructionBytesT-statesDescription
EX DE,HL14Swap DE ↔ HL
EX AF,AF'14Swap AF ↔ AF' (alternate flags)
EXX14Swap BC/DE/HL ↔ BC'/DE'/HL' all at once
EX (SP),HL119Swap 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

InstructionBytesT-statesFlags
LDIR221/16H,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

InstructionBytesT-statesFlags
NOP14None affected

HALT - Halt CPU

InstructionBytesT-statesFlags
HALT14None affected

DI / EI - Disable/Enable Interrupts

InstructionBytesT-statesFlags
DI14None affected
EI14None 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:

ModeSets viaBehaviourT-states (interrupt entry)
IM 0IM 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 1IM 1 (ED 56)CPU pushes PC, jumps to fixed $0038. Used by ZX Spectrum.13
IM 2IM 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.

InstructionBytesT-statesEffect
IM 0 / IM 1 / IM 228Select interrupt mode
RETI214Return from maskable interrupt; signals to peripherals
RETN214Return 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

Performance Notes

Fastest instructions:

  • Register operations: 4 T-states
  • XOR A (clear A): 4 T-states
  • INC/DEC register: 4 T-states

Optimisation tips:

  1. Use register operations over memory.
  2. 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).
  3. 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.
  4. Use DJNZ for counted loops — 13/8 T-states with no fiddling with B by hand.
  5. Use EX AF,AF' + EXX for fast register backup in interrupt handlers (8T total vs ~50T for the equivalent push/pop sequence).
  6. 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.
  7. Unroll loops in speed-critical code (raster effects, audio mixing, sprite blitting).

See also