Skip to content

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
ADCADC A,s / ADC HL,ss
Add 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).
ADDADD A,s / ADD HL,ss / ADD IX,ss
Add without carry: A ← A + s, or a 16-bit HL/IX/IY ← +ss. The 16-bit form affects only H, N and C.
ANDAND s
Bitwise AND of A with s, result in A. Sets H, clears C and N, and sets S Z and P (parity).
BITBIT b,s
Test 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.
CALLCALL nn / CALL cc,nn
Push the return address and jump to nn. The conditional form CALL cc,nn only calls when condition cc holds.
CCFCCF
Complement the carry flag (CF ← ¬CF); the previous CF is copied into H and N is cleared.
CPCP s
Compare 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).
CPDCPD
Compare (HL) with A, then decrement HL and BC. Sets Z on a match; P/V reflects whether BC is still non-zero.
CPDRCPDR
Repeat CPD — compare and decrement HL/BC — until A matches (HL) or BC reaches 0. A block search downwards.
CPICPI
Compare (HL) with A, then increment HL and decrement BC. Sets Z on a match; P/V reflects whether BC is still non-zero.
CPIRCPIR
Repeat CPI — compare and increment HL, decrement BC — until A matches (HL) or BC reaches 0. A block search upwards.
CPLCPL
Complement A (one's complement, A ← ¬A). Sets H and N; the other flags are unchanged.
DAADAA
Decimal-adjust A after a BCD add or subtract, correcting the result to packed binary-coded decimal using the H and C flags.
DBDB n[,n…]
Define byte(s) — emit each comma-separated operand as a single byte at the current address. Used for data tables and text.
DECDEC r / DEC (HL) / DEC ss
Decrement the 8-bit register/memory operand (sets S Z H P/V and N) or a 16-bit register pair (no flags affected).
DIDI
Disable the maskable interrupt (resets both interrupt-enable flip-flops). Interrupts stay off until EI.
DJNZDJNZ e
Decrement B and, if it is now non-zero, jump relative to e (−126…+129 bytes). The standard counted-loop instruction.
DSDS n
Define storage — reserve n zero-filled bytes at the current address, advancing the location counter.
DWDW nn[,nn…]
Define word(s) — emit each operand as a little-endian 16-bit value (low byte first), the way the Z80 stores addresses.
EIEI
Enable the maskable interrupt. Takes effect after the following instruction, so a RET/RETI can run first.
EXEX DE,HL / EX AF,AF' / EX (SP),HL
Exchange register pairs: DE↔HL, the AF shadow set, or the top of the stack with HL/IX/IY.
EXXEXX
Exchange BC, DE and HL with their shadow registers BC′ DE′ HL′ in one instruction. AF is not affected.
HALTHALT
Suspend the CPU (executing NOPs internally) until an interrupt or reset occurs. Used to synchronise with interrupts.
IMIM 0 / IM 1 / IM 2
Select the interrupt mode: 0 (device supplies an instruction), 1 (RST $38), or 2 (vectored via the I register).
ININ 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.
INCINC r / INC (HL) / INC ss
Increment the 8-bit register/memory operand (sets S Z H P/V, clears N) or a 16-bit register pair (no flags affected).
INDIND
Input from port (C) into (HL), then decrement HL and B. One step of a downward input block.
INDRINDR
Repeat IND until B reaches 0: input a block from port (C) into memory, decrementing HL each byte.
INIINI
Input from port (C) into (HL), then increment HL and decrement B. One step of an upward input block.
INIRINIR
Repeat INI until B reaches 0: input a block from port (C) into memory, incrementing HL each byte.
JPJP 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).
JRJR e / JR cc,e
Relative jump to e (−126…+129 bytes from the instruction). The conditional form allows only NZ, Z, NC and C.
LDLD dst,src
The 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).
LDDLDD
Copy (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.
LDDRLDDR
Repeat 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).
LDILDI
Copy (HL) to (DE), then increment HL and DE and decrement BC. One step of an upward block move.
LDIRLDIR
Repeat LDI until BC reaches 0 — the classic ascending block copy of BC bytes from HL to DE.
NEGNEG
Negate A (two's complement, A ← 0 − A). Sets the flags, including C when A was non-zero.
NOPNOP
No operation — does nothing for four T-states. Used for timing padding or to blank out code.
OROR s
Bitwise OR of A with s, result in A. Clears H, C and N; sets S Z and P (parity).
ORGORG nn
Set 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.
OTDROTDR
Repeat OUTD until B reaches 0 — output a block from memory to port (C), decrementing HL each byte.
OTIROTIR
Repeat OUTI until B reaches 0 — output a block from memory to port (C), incrementing HL each byte.
OUTOUT (n),A / OUT (C),r
Write 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.
OUTDOUTD
Output (HL) to port (C), then decrement HL and B. One step of a downward output block.
OUTIOUTI
Output (HL) to port (C), then increment HL and decrement B. One step of an upward output block.
POPPOP ss
Pop two bytes off the stack into a register pair (BC, DE, HL, AF, IX or IY); SP increases by 2.
PUSHPUSH ss
Push a register pair (BC, DE, HL, AF, IX or IY) onto the stack; SP decreases by 2.
RESRES b,s
Reset (clear) bit b (0-7) of the operand to 0. No flags are affected.
RETRET / RET cc
Return from a subroutine by popping the address off the stack. RET cc returns only when condition cc holds.
RETIRETI
Return from a maskable-interrupt handler; signals completion to Z80 peripherals (the daisy chain) as well as popping the return address.
RETNRETN
Return from a non-maskable-interrupt handler, restoring the interrupt-enable state saved when the NMI was taken.
RLRL s
Rotate the operand left through the carry flag (9-bit rotate: CF → bit 0, bit 7 → CF). Sets S Z P, clears H and N.
RLARLA
Rotate A left through carry — the fast, flag-light accumulator version of RL A (only H, N and C change).
RLCRLC s
Rotate the operand left circularly (bit 7 → bit 0 and → CF). Sets S Z P, clears H and N.
RLCARLCA
Rotate A left circularly — the fast accumulator version of RLC A (only H, N and C change).
RLDRLD
Rotate 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).
RRRR s
Rotate the operand right through the carry flag (9-bit rotate: CF → bit 7, bit 0 → CF). Sets S Z P, clears H and N.
RRARRA
Rotate A right through carry — the fast accumulator version of RR A (only H, N and C change).
RRCRRC s
Rotate the operand right circularly (bit 0 → bit 7 and → CF). Sets S Z P, clears H and N.
RRCARRCA
Rotate A right circularly — the fast accumulator version of RRC A (only H, N and C change).
RRDRRD
Rotate one BCD digit right across A and (HL) — the mirror of RLD, shifting the nibbles the other way.
RSTRST p
Push the return address and call one of the eight fixed restart vectors ($00, $08, $10, $18, $20, $28, $30, $38). A one-byte call.
SBCSBC A,s / SBC HL,ss
Subtract with carry (borrow): A ← A − s − CF, or the 16-bit HL ← HL − ss − CF. Sets N and the other flags.
SCFSCF
Set the carry flag (CF ← 1). Clears H and N; the other flags are unchanged.
SETSET b,s
Set bit b (0-7) of the operand to 1. No flags are affected.
SLASLA s
Arithmetic shift left: bit 7 → CF, 0 → bit 0 (a multiply by two). Sets S Z P, clears H and N.
SRASRA s
Arithmetic shift right: bit 0 → CF, bit 7 preserved (sign-extending) — a signed divide by two. Sets S Z P, clears H and N.
SRLSRL s
Logical shift right: bit 0 → CF, 0 → bit 7 — an unsigned divide by two. Sets S Z P, clears H and N.
SUBSUB s
Subtract s from A (A ← A − s), setting N and the other flags. C is set on borrow (A < s unsigned).
XORXOR s
Bitwise 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:

SymbolMeans
r8-bit register — A B C D E H L
san 8-bit source — a register, n, (HL), (IX+d), (IY+d)
n8-bit immediate value; nn a 16-bit immediate
ss16-bit register pair — BC DE HL SP (or AF, IX, IY)
dsigned index displacement inside (IX+d) / (IY+d)
erelative jump target (the label you jump to)
cccondition — NZ Z NC C PO PE P M
bbit number, 0–7
prestart 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-digit 0FFh
  • Binary — %1010 or 0b1010
  • 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's REM/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 — reserve n zero-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.

Released under GNU GPL v3.0. Some ROM images are third-party copyrighted works, separate to this project, strictly for personal/educational purposes.