Z80 assembly reference
Every documented Z80 instruction, plus the assembler directives, understood by the built-in assembly editor. This one reference covers every Z80 machine Basically supports — the ZX81, ZX80, ZX Spectrum (48K & 128K), TRS-80, Amstrad CPC, Sony HB-10P, the Exidy Sorcerer and the SAM Coupé all share the identical instruction set and assembler syntax. What differs between them is only the memory map (where a block may live and the entry addresses you call), which stays on each machine's own hardware page.
The Altair 8800 uses this reference too, though its processor is the earlier Intel 8080: the Z80 was designed to run 8080 code, so every 8080 instruction is here under its Z80 name and assembles to the same bytes. Only the reverse is a trap — an instruction the Z80 added will run on the emulated Altair but would not have run on the real machine.
Use the search box to filter by mnemonic, the buttons to show only Instructions or Directives, and the Name / Kind headers to re-sort. Undocumented opcodes (SLL, the IXH/IXL register halves) are not assembled and disassemble back as DB data.
Instruction Directive
| Syntax & description | |
|---|---|
ADC | ADC A,s / ADC HL,ssAdd with carry: A ← A + s + CF, or the 16-bit HL ← HL + ss + CF. Updates the flags (the 8-bit form sets S Z H P/V N C). |
ADD | ADD A,s / ADD HL,ss / ADD IX,ssAdd without carry: A ← A + s, or a 16-bit HL/IX/IY ← +ss. The 16-bit form affects only H, N and C. |
AND | AND sBitwise AND of A with s, result in A. Sets H, clears C and N, and sets S Z and P (parity). |
BIT | BIT b,sTest bit b (0-7) of s and set the Z flag to its complement; the operand is left unchanged. Usually followed by a conditional jump. |
CALL | CALL nn / CALL cc,nnPush the return address and jump to nn. The conditional form CALL cc,nn only calls when condition cc holds. |
CCF | CCFComplement the carry flag (CF ← ¬CF); the previous CF is copied into H and N is cleared. |
CP | CP sCompare s with A by computing A − s and setting the flags, but discarding the result (A is unchanged). Z means equal; C means A < s (unsigned). |
CPD | CPDCompare (HL) with A, then decrement HL and BC. Sets Z on a match; P/V reflects whether BC is still non-zero. |
CPDR | CPDRRepeat CPD — compare and decrement HL/BC — until A matches (HL) or BC reaches 0. A block search downwards. |
CPI | CPICompare (HL) with A, then increment HL and decrement BC. Sets Z on a match; P/V reflects whether BC is still non-zero. |
CPIR | CPIRRepeat CPI — compare and increment HL, decrement BC — until A matches (HL) or BC reaches 0. A block search upwards. |
CPL | CPLComplement A (one's complement, A ← ¬A). Sets H and N; the other flags are unchanged. |
DAA | DAADecimal-adjust A after a BCD add or subtract, correcting the result to packed binary-coded decimal using the H and C flags. |
DB | DB n[,n…]Define byte(s) — emit each comma-separated operand as a single byte at the current address. Used for data tables and text. |
DEC | DEC r / DEC (HL) / DEC ssDecrement the 8-bit register/memory operand (sets S Z H P/V and N) or a 16-bit register pair (no flags affected). |
DI | DIDisable the maskable interrupt (resets both interrupt-enable flip-flops). Interrupts stay off until EI. |
DJNZ | DJNZ eDecrement B and, if it is now non-zero, jump relative to e (−126…+129 bytes). The standard counted-loop instruction. |
DS | DS nDefine storage — reserve n zero-filled bytes at the current address, advancing the location counter. |
DW | DW nn[,nn…]Define word(s) — emit each operand as a little-endian 16-bit value (low byte first), the way the Z80 stores addresses. |
EI | EIEnable the maskable interrupt. Takes effect after the following instruction, so a RET/RETI can run first. |
EX | EX DE,HL / EX AF,AF' / EX (SP),HLExchange register pairs: DE↔HL, the AF shadow set, or the top of the stack with HL/IX/IY. |
EXX | EXXExchange BC, DE and HL with their shadow registers BC′ DE′ HL′ in one instruction. AF is not affected. |
HALT | HALTSuspend the CPU (executing NOPs internally) until an interrupt or reset occurs. Used to synchronise with interrupts. |
IM | IM 0 / IM 1 / IM 2Select the interrupt mode: 0 (device supplies an instruction), 1 (RST $38), or 2 (vectored via the I register). |
IN | IN A,(n) / IN r,(C)Read a byte from an I/O port into a register. The (C) form uses BC as the 16-bit port address and sets flags; IN A,(n) does not. |
INC | INC r / INC (HL) / INC ssIncrement the 8-bit register/memory operand (sets S Z H P/V, clears N) or a 16-bit register pair (no flags affected). |
IND | INDInput from port (C) into (HL), then decrement HL and B. One step of a downward input block. |
INDR | INDRRepeat IND until B reaches 0: input a block from port (C) into memory, decrementing HL each byte. |
INI | INIInput from port (C) into (HL), then increment HL and decrement B. One step of an upward input block. |
INIR | INIRRepeat INI until B reaches 0: input a block from port (C) into memory, incrementing HL each byte. |
JP | JP nn / JP cc,nn / JP (HL)Unconditional or conditional absolute jump to nn. JP (HL)/(IX)/(IY) jumps to the address held in the register (an indirect, computed jump). |
JR | JR e / JR cc,eRelative jump to e (−126…+129 bytes from the instruction). The conditional form allows only NZ, Z, NC and C. |
LD | LD dst,srcThe universal copy: load a register, register pair or memory location from another. Never affects flags (except LD A,I / LD A,R, which set S and Z). |
LDD | LDDCopy (HL) to (DE), then decrement HL, DE and BC. One step of a downward block move; P/V reflects whether BC is still non-zero. |
LDDR | LDDRRepeat LDD until BC reaches 0 — a descending block copy from HL to DE (use when the ranges overlap and the destination is above the source). |
LDI | LDICopy (HL) to (DE), then increment HL and DE and decrement BC. One step of an upward block move. |
LDIR | LDIRRepeat LDI until BC reaches 0 — the classic ascending block copy of BC bytes from HL to DE. |
NEG | NEGNegate A (two's complement, A ← 0 − A). Sets the flags, including C when A was non-zero. |
NOP | NOPNo operation — does nothing for four T-states. Used for timing padding or to blank out code. |
OR | OR sBitwise OR of A with s, result in A. Clears H, C and N; sets S Z and P (parity). |
ORG | ORG nnSet the assembly origin for the code that follows. It must agree with the block's own load address — the block editor fixes that from where the block sits in the listing. |
OTDR | OTDRRepeat OUTD until B reaches 0 — output a block from memory to port (C), decrementing HL each byte. |
OTIR | OTIRRepeat OUTI until B reaches 0 — output a block from memory to port (C), incrementing HL each byte. |
OUT | OUT (n),A / OUT (C),rWrite a register to an I/O port. OUT (n),A uses an 8-bit port; OUT (C),r uses BC as the 16-bit port address. |
OUTD | OUTDOutput (HL) to port (C), then decrement HL and B. One step of a downward output block. |
OUTI | OUTIOutput (HL) to port (C), then increment HL and decrement B. One step of an upward output block. |
POP | POP ssPop two bytes off the stack into a register pair (BC, DE, HL, AF, IX or IY); SP increases by 2. |
PUSH | PUSH ssPush a register pair (BC, DE, HL, AF, IX or IY) onto the stack; SP decreases by 2. |
RES | RES b,sReset (clear) bit b (0-7) of the operand to 0. No flags are affected. |
RET | RET / RET ccReturn from a subroutine by popping the address off the stack. RET cc returns only when condition cc holds. |
RETI | RETIReturn from a maskable-interrupt handler; signals completion to Z80 peripherals (the daisy chain) as well as popping the return address. |
RETN | RETNReturn from a non-maskable-interrupt handler, restoring the interrupt-enable state saved when the NMI was taken. |
RL | RL sRotate the operand left through the carry flag (9-bit rotate: CF → bit 0, bit 7 → CF). Sets S Z P, clears H and N. |
RLA | RLARotate A left through carry — the fast, flag-light accumulator version of RL A (only H, N and C change). |
RLC | RLC sRotate the operand left circularly (bit 7 → bit 0 and → CF). Sets S Z P, clears H and N. |
RLCA | RLCARotate A left circularly — the fast accumulator version of RLC A (only H, N and C change). |
RLD | RLDRotate one BCD digit left across A and (HL): low nibble of (HL) → its high nibble, high nibble of (HL) → low nibble of A, low nibble of A → low nibble of (HL). |
RR | RR sRotate the operand right through the carry flag (9-bit rotate: CF → bit 7, bit 0 → CF). Sets S Z P, clears H and N. |
RRA | RRARotate A right through carry — the fast accumulator version of RR A (only H, N and C change). |
RRC | RRC sRotate the operand right circularly (bit 0 → bit 7 and → CF). Sets S Z P, clears H and N. |
RRCA | RRCARotate A right circularly — the fast accumulator version of RRC A (only H, N and C change). |
RRD | RRDRotate one BCD digit right across A and (HL) — the mirror of RLD, shifting the nibbles the other way. |
RST | RST pPush the return address and call one of the eight fixed restart vectors ($00, $08, $10, $18, $20, $28, $30, $38). A one-byte call. |
SBC | SBC A,s / SBC HL,ssSubtract with carry (borrow): A ← A − s − CF, or the 16-bit HL ← HL − ss − CF. Sets N and the other flags. |
SCF | SCFSet the carry flag (CF ← 1). Clears H and N; the other flags are unchanged. |
SET | SET b,sSet bit b (0-7) of the operand to 1. No flags are affected. |
SLA | SLA sArithmetic shift left: bit 7 → CF, 0 → bit 0 (a multiply by two). Sets S Z P, clears H and N. |
SRA | SRA sArithmetic shift right: bit 0 → CF, bit 7 preserved (sign-extending) — a signed divide by two. Sets S Z P, clears H and N. |
SRL | SRL sLogical shift right: bit 0 → CF, 0 → bit 7 — an unsigned divide by two. Sets S Z P, clears H and N. |
SUB | SUB sSubtract s from A (A ← A − s), setting N and the other flags. C is set on borrow (A < s unsigned). |
XOR | XOR sBitwise exclusive-OR of A with s, result in A. Clears H, C and N; sets S Z and P. XOR A is the idiomatic way to zero A. |
Showing 71 of 71 keywords
Operand notation
The Syntax column uses the conventional Z80 placeholders:
| Symbol | Means |
|---|---|
r | 8-bit register — A B C D E H L |
s | an 8-bit source — a register, n, (HL), (IX+d), (IY+d) |
n | 8-bit immediate value; nn a 16-bit immediate |
ss | 16-bit register pair — BC DE HL SP (or AF, IX, IY) |
d | signed index displacement inside (IX+d) / (IY+d) |
e | relative jump target (the label you jump to) |
cc | condition — NZ Z NC C PO PE P M |
b | bit number, 0–7 |
p | restart vector — $00 $08 $10 $18 $20 $28 $30 $38 |
Registers, condition codes and index expressions like (IX+5) are recognised as such, so they can't be used as label names.
Numbers, labels & comments
The assembler accepts several number spellings, in any case:
- Hex —
$FF,0xFF, or a leading-digit0FFh - Binary —
%1010or0b1010 - Decimal —
65535
Disassembly always writes hex with a $ sigil (two digits for a byte, four for a word), so $ never means "current address".
A label is a name followed by a colon at the start of a line (loop:); refer to it by name in a jump or as an address. Operands may use simple +/- expressions (table+2). Everything after a semicolon (;) is a comment.
Directives
Four pseudo-ops control layout and data:
ORG nn— set the origin. It must match the block's own load address, which the block editor fixes from where the block'sREM/record sits in the listing, so you rarely change it by hand.DB n[,n…]— emit literal bytes (data tables, text).DW nn[,nn…]— emit little-endian 16-bit words.DS n— reservenzero-filled bytes.
Where blocks live on each machine
The address ranges a routine may occupy, the default load address, and the entry points you call from BASIC are machine-specific — see the Memory section on each machine's hardware page: ZX81, ZX80, ZX Spectrum, TRS-80, Amstrad CPC, Sony HB-10P, Exidy Sorcerer, SAM Coupé and Altair 8800.
See also the machine code guide and the cross-dialect Machine code & data blocks overview.