Z80 instruction set

Microprocessor instruction set From Wikipedia, the free encyclopedia

The Zilog Z80 is an 8-bit microprocessor introduced in 1976. The instruction set was designed to be upward binary compatible with the Intel 8080. Intel 8080 instructions are one to three bytes long whereas the Z80 requires up to four bytes per instruction.

Zilog Z80 CPU. 1976 date code.

Zilog continued to expand the instruction set of the Z80 with several successors including the Z180, Z280, and Z380. The latest iteration, the eZ80, was introduced in 2001 and was available for purchase as of 2025. The instruction set also appears on non-Zilog CPUs such as the Hitachi HD64180,[1] Mitsui R800, and the Eastern Bloc U880.[2]

Instruction set

The Z80 uses 252 out of the available 256 codes as single byte opcodes (the "root instructions"), most of which are inherited from the 8080. The four remaining codes are used extensively as opcode prefixes:[3] CB and ED enable extra instructions, and DD or FD select IX or IY respectively in place of HL. This scheme gives the Z80 a large number of permutations of instructions and registers. Zilog categorizes these into 158 different "instruction types", 78 of which are the same as those of the Intel 8080.[3] This allows operation of all 8080 programs on a Z80. The Zilog documentation[4] further groups instructions into categories. Most are from the 8080, others are entirely new like the block and bit instructions, and other 8080 instructions with more versatile addressing modes, like the 16-bit loads, I/O, rotates/shifts, and relative jumps. The categories are:

  • Load and exchange
  • Block transfer and search
  • Arithmetic and logical
  • Rotate and shift
  • Bit manipulation (set, reset, test)
  • Jump, call, and return
  • Input/output
  • CPU control

Encoding order

To expand on the 8080 instruction set, Z80 instructions may require a IX/IY override, an opcode prefix, or both. Any one instruction may contain up to four components. The components of the instruction are assembled in the following order:[5]

IX/IY override
CB or ED prefix
(IX/IY + n) offset if CB
Opcode
(IX/IY + n) offset if no CB
data or address

Root instructions

The root opcodes include all the 8080 opcodes. The Z80 adds eight new one-byte instructions, two opcode prefixes, and the IX and IY overrides.[6] Colored rows indicate new Z80 instructions.

More information Opcode, Operands ...
OpcodeOperandsMnemonicDescription
76543210b2b3
00000000NOPNo operation
00RP0001datlodathiLD rp,dataRP ← data
00RP0010LD (rp),A(RP) ← A [BC or DE only]
00RP0011INC rpRP ← RP + 1
00DDD100INC dddDDD ← DDD + 1
00DDD101DEC dddDDD ← DDD - 1
00DDD110dataLD ddd,dataDDD ← data
00000111RLCAA1-7 ← A0-6; A0 ← Cy ← A7
00RP1001ADD rpHL ← HL + RP
00RP1010LD A,(rp)A ← (RP) [BC or DE only]
00RP1011DEC rpRP ← RP - 1
00001000EX AF,AF'AF ↔ AF
00001111RRCAA0-6 ← A1-7; A7 ← Cy ← A0
00010000offsetDJNZ offsetB = B - 1; if B ≠ 0 then PC ← PC + offset
00010111RLAA1-7 ← A0-6; Cy ← A7; A0 ← Cy
00011000offsetJR offsetPC ← PC + offset
00011111RRAA0-6 ← A1-7; Cy ← A0; A7 ← Cy
001CC000offsetJR cc,offsetIf CC0-1 true, PC ← PC + offset (Only 2 bits of CC used: NZ, Z, NC, C)
00100010addloaddhiLD add,HL(add) ← HL
00100111DAAIn N flag = 0 {If A0-3 > 9 OR AC = 1 then A ← A + 6;

then if A4-7 > 9 OR Cy = 1 then A ← A + 0x60} else {do post-subtract DAA}

00101010addloaddhiLD HL,addHL ← (add)
00101111CPLA ← ¬A
00110010addloaddhiLD add,A(add) ← A
00110111SCFCy ← 1
00111010addloaddhiLD A,addA ← (add)
00111111CCFCy ← ¬Cy
01DDDSSSLD ddd,sssDDD ← SSS
01110110HALTHalt
10ALUSSSADD ADC SUB SBC AND XOR OR CP sssA ← A [ALU operation] SSS
11CC000RET ccIf cc true, PC ← (SP), SP ← SP + 2
11RP0001POP rpRP ← (SP), SP ← SP + 2
11CC010addloaddhiJP cc,addIf cc true, PC ← add
11000011addloaddhiJP addPC ← add
11CC100addloaddhiCALL cc,addIf cc true, SP ← SP - 2, (SP) ← PC, PC ← add
11RP0101PUSH rpSP ← SP - 2, (SP) ← RP
11ALU110dataADD ADC SUB SBC AND XOR OR CP dataA ← A [ALU operation] data
11N111RST nSP ← SP - 2, (SP) ← PC, PC ← N
11001001RETPC ← (SP), SP ← SP + 2
11001011CB prefixSee CB prefix table
11001101addloaddhiCALL addSP ← SP - 2, (SP) ← PC, PC ← add
11010011portOUT port,APort(A:port) ← A[a]
11011001EXXBC ↔ BC, DE ↔ DE, HL ↔ HL
11011011portIN A,portA ← Port(A:port) [a]
11011101IX overrideHL becomes IX; (HL) becomes (IX + offset)
11100011EX (SP),HL(SP) ↔ HL
11101001JP (HL)PC ← HL
11101011EX DE,HLHL ↔ DE
11101101ED prefixSee ED prefix table
11110011DIIFF1 ← IFF2 ← 0; Disable interrupts
11111001LD SP,HLSP ← HL
11111011EIIFF1 ← IFF2 ← 1; Enable interrupts
11111101IY overrideHL becomes IY; (HL) becomes (IY + offset)
76543210b2b3MnemonicDescription
SSS DDD210CCALURP
B000NZADD (A ← A + arg)BC
C001ZADC (A ← A + arg + Cy)DE
D010NCSUB (A ← A - arg)HL
E011CSBC (A ← A - arg - Cy)SP or AF
H100POAND (A ← A ∧ arg)
L101PEXOR (A ← A ⊻ arg)
(HL)110POR (A ← A ∨ arg)
A111NCP (A - arg)
SSS DDD210CCALU
Close
  1. OUT port,A and IN A,port instructions generate a 16-bit port address with the 8-bit immediate port number forming the lower part of the address and the A register forming the upper part. Typically, devices will only decode the lower part. In contrast, the 8080 duplicates the immediate port number on both the upper and lower address bus.

Instructions prefixed with ED

The ED-prefixed opcodes are a catch-all of new Z80 instructions that could not be encoded in one byte. This group encompasses only 60 of 256 available opcodes.[6]

More information Opcode, Operands ...
OpcodeOperandsMnemonicDescription
76543210b2b3
01DDD000IN ddd,(C)[a]DDD ← port(BC) [Except (HL)] (Port number is 16 bits)
01SSS001OUT (C),sssport(BC) ← SSS [Except (HL)] (Port number is 16 bits)
01RP0010SBC HL,ssHL ← HL – ss – CY
01RP0011addloaddhiLD (add), ss(add) ← RP
01000100NEGA ← 0 - A
01000101RETNPC ← (SP); SP ← SP + 2; IFF1 ← IFF2[b]
010NN110IM nInterrupt mode 0, 1, 2 (encoded 0, 2, 3)
01000111LD I,Ainterrupt control vector ← A
01RP1010ADC HL,ssHL ← HL + ss + CY
01RP1011addloaddhiLD dd, (add)RP ← (add)
01001101RETIPC ← (SP); SP ← SP + 2; IFF1 ← IFF2[b]
01001111LD R,Arefresh ← A
01010111LD A,IA ← interrupt control vector [c]
01011111LD A,RA ← refresh [c]
01100111RRDA0-3 ← (HL)0-3; (HL)7-4 ← A0-3; (HL)0-3 ← (HL)7-4
01101111RLDA0-3 ← (HL)7-4; (HL)0-3 ← A0-3; (HL)7-4 ← (HL)0-3
101RD000LDI LDIR LDD LDDR(DE) ← (HL); HL ← HL ± 1; DE ← DE ± 1; BC ← BC - 1 [d][e]
101RD001CPI CPIR CPD CPDRA - (HL); HL ← HL ± 1; BC ← BC - 1 [d][e][f]
101RD010INI INIR IND INDR(HL) ← port(BC); HL ← HL ± 1; B ← B – 1 [d]
101RD011OUTI OTIR OUTD OTDRB ← B – 1; port(BC) ← (HL); HL ← HL ± 1 [d][7]
76543210b2b3MnemonicDescription
Close
  1. Byte input sets the flags unlike IN A,n
  2. RETN and RETI are identical and restore IFF1. Z80 compatible interrupt devices watch for RETI by sniffing the data bus while M1- is asserted for 0xED followed by 0x4D.
  3. LD A,I and LD A,R are the only two LD instructions that set flags. Additionally, IFF2 is loaded into the P/V flag. C unaffected.
  4. When D = 1, pointers HL and DE decrement. When R = 1, operation repeats until BC or B = 0. All block IO instructions output BC, not just C, as the port address.
  5. LDI, LDD, CPI, and CPD set P/V if BC – 1 ≠ 0. This is useful for loop control when not using repeat.
  6. CPIR/CPDR terminate early if A = (HL).

Instructions prefixed with CB

Shift and rotate instructions. SLL is an undefined instruction.

The CB-prefixed opcodes cover shifts and rotates plus the bit test, clear, and set instructions. All of these instructions can be used with any register or memory. The (HL) form of these instructions can be combined with an IX or IY opcode prefix to operate on (IX+d) or (IY+d). This group encompasses 248 of 256 available opcodes.[6]

More information Opcode, Mnemonic ...
OpcodeMnemonicDescription
76543210
00000SSSRLC rR1-7 ← R0-6; R0 ← Cy ← R7
00001SSSRRC rR0-6 ← R1-7; R7 ← Cy ← R0
00010SSSRL rR1-7 ← R0-6; Cy ← R7; R0 ← Cy
00011SSSRR rR0-6 ← R1-7; Cy ← R0; R7 ← Cy
00100SSSSLA rCy ← R7; R1-7 ← R0-6; R0 ← 0
00101SSSSRA rCy ← R0; R0-6 ← R1-7
00111SSSSRL rCy ← R0; R0-6 ← R1-7; R7 ← 0
01bitSSSBIT b,rR ∧ (1 << b)
10bitSSSRES b,rR ← R ∧ ¬(1 << b)
11bitSSSSET b,rR ← R ∨ (1 << b)
76543210MnemonicDescription
Close

IX and IY overrides

Two opcode prefixes expand the number of Z80 addressing modes to access the new IX and IY index registers:

  • Prefix DD changes HL to IX or (HL) to (IX+displacement)
  • Prefix FD changes HL to IY or (HL) to (IY+displacement)

The index registers, IX and IY, were intended as flexible 16-bit pointers, enhancing the ability to manipulate memory, stack frames, and data structures. Officially, they were treated as 16-bit only. In reality, they were implemented as a pair of 8-bit registers[8] in the same fashion as the HL register, which is accessible either as 16 bits or separately as the high and low registers. The binary opcodes were identical, but preceded by a new opcode prefix.[9]

Undocumented uses of IX/IY

Zilog published the opcodes and related mnemonics for the intended functions, but did not document the fact that every opcode that allowed manipulation of the HL register was equally valid for the 8-bit halves of the IX and IY registers. For example, opcode 26h followed by an immediate byte value forms the instruction LD H,n. It will load the n immediate value into the H register. Preceding this two-byte instruction with the IX register's opcode prefix, DD, would instead result in the most significant 8 bits of the IX register being loaded with that same value. A notable exception to this would be instructions similar to LD H,(IX+d) which make use of both the HL and IX or IY registers in the same instruction.[9] In this case the DD prefix is only applied to the (IX+d) portion of the instruction.

Accessing the IX/IY halves can speed some operations. To load DE into IX using official instructions, one could use PUSH DE and POP IX, taking 25 cycles. Using the half-load feature, the same could be coded as LD IXL,E and LD IXH,D, saving 9 cycles but taking an extra byte.

The IX and IY halves can also hold operands for 8-bit arithmetic, logical, and compare instructions, sparing the regular 8-bit registers for other use. Any IX/IY half can be incremented or decremented or loaded to or from any 8-bit register except H or L.[9]

Instruction synonyms

The Z80 expands the 8080 instruction set and makes it more orthogonal. A byproduct of this is there are certain instruction functions that map to two different instruction encodings. In a few cases there is an 8080 instruction coding that is smaller and faster than the orthogonal Z80 encoding.[5] Some examples:

  • The Z80 introduced orthogonal versions of LD RP,(nn) and LD (nn),RP instructions where RP can be any register pair or SP. The Z80 assembler substitutes the 8080 version of LD HL,(nn) and LD (nn),HL to save a byte and four clocks.
  • RL A, RR A, RLC A, RRC A, and SLA A instructions are part of the Z80 CB-prefixed rotates. The 8080 RLA, RRA, RLCA, RRCA, and ADD A,A instructions are a byte smaller and twice as fast.
  • The Z80 introduced a two-byte unconditional jump, JR. Although larger, the three-byte 8080 JP is two clocks faster.
  • The Z80 added two-byte conditional jumps: JR NZ, JR Z, JR NC, and JR C as alternates to the 8080 three byte conditional jumps: JP NZ, JP Z, JP NC, and JP C. Although the two-byte forms are two clocks slower when taken, they are three clocks faster when not taken.
  • The Z80 DJNZ instruction is half the size of the 8080 equivalent instructions and one clock faster.

References

Related Articles

Wikiwand AI