Convention de lecture pour le jeu d'instructions.
Préambule.
La description du jeu d'instructions suit un ordre logique dans un but d'apprentissage, il ne doit pas être vu comme une documentation technique brute. Ainsi, les premières instructions décrites sont les instructions de chargement mémoire/registre, puis les instructions de comparaison et celles de sauts conditionnels. Enfin, les autres instructions réalisant des opérations ou calculs sur les registres. Voici un exemple simple de programme Z80:
 LD A,(variable1) ; charger dans A l'octet présent à l'adresse variable1
 LD HL,variable2 ; charger dans HL l'adresse de variable2
 CP A,(HL) ; comparer la valeur de A avec l'octet à l'adresse HL (soit variable2)
 JR Z,egalite ; si la soustraction de A par (HL) vaut zéro, c'est que les deux valeurs sont égales, alors on réalise le saut vers egalite
Abréviations pour les opérandes.
 reg8 : registre 8 bits (sauf I ou R)
 reg16 : registre 16 bits (sauf PC,SP,IR)
 dep8 : déplacement relatif 8 bits (-128 à +127)
 n : valeur immédiate 8 bits
 nn : valeur immédiate 16 bits
 (reg16): valeur en mémoire indexée par un registre 16 bits (sauf PC,SP,IR)
 (nn) : valeur en mémoire indexée en absolu par une valeur 16 bits
L'utilisation des registres IX et IY en adressage peut toujours s'accompagner d'un déplacement de type dep8.
Valeurs littérales.
Il est important de signaler que les valeurs littérales exprimées ici représentent un consensus global entre assembleurs Z80 mais les assembleurs les plus anciens ne supportent pas toutes les syntaxes.
 12345 ; valeur décimale
 #1234 ; valeur hexadécimale
 0x1234 ; valeur hexadécimale
 &1234 ; valeur hexadécimale héritée du Basic Locomotive (déconseillée pour confusion avec l'opérateur AND de certains assembleurs)
 $1234 ; valeur hexadécimale héritée de Motorola (déconseillé pour éviter la confusion avec l'adresse courante qui est $)
 %01010 ; valeur binaire
 0b1010 ; valeur binaire
 @4736 ; valeur octale
 $ ; adresse de l'instruction en cours (utilisé principalement pour des sauts relatifs)
Valeurs remarquables.
Le Z80 est conçu pour traiter des données 8 bits ou 16 bits. Afin d'appréhender plus facilement les retenues ou les bits susceptibles d'être décalées, il faut faire ses gammes avec les valeurs dîtes remarquables et les connaitre par cœur.
Valeur de chaque bit
Comprendre le principe de la pile.
La plupart des microprocesseurs possèdent un mécanisme de pile pour enregistrer (empiler) des informations et les restituer à la demande. Cette pile est une structure de donnée basée sur le principe de dernier arrivé, premier sorti (en anglais LIFO pour "last in, first out"). Sur le Z80, c'est le registre SP qui indique l'adresse en mémoire vive du dernier élément empilé. Les instructions PUSH et POP, mais aussi CALL et RET effectuent des sauvegardes et des restitutions depuis la pile.
Dans un langage évolué, l'utilisation de la pile est transparent et géré par le compilateur. En assembleur, toute fonction appelée par un CALL doit logiquement se terminer par un RET. Si on sauvegarde un certain nombre de registre dans la pile (pour pouvoir les modifier par exemple), il est impératif d'en restituer le même nombre pour ne pas faire déborder la pile.
Quand les interruptions sont actives, le programme en cours peut-être interrompu à tout moment. À cet instant, le processeur enregistre l'adresse courante (comme avec un CALL) dans la pile et exécute le programme défini pour les interruptions. Afin de ne pas corrompre l'exécution du programme interrompu, le programme sous interruption doit enregistrer tous les registres qu'il va modifier. La méthode la plus simple est d'utiliser la pile. En fin de routine, le programme sous interruption restituent un à un les registres. Ré-active les interruptions puis RET(ourne) au programme qui a été interrompu.
Dans le chapitre sur la programmation avancée, nous verrons des exemples détournés de l'utilisation de la pile. Tant pour écrire dans la mémoire plus rapidement que pour lire des paquets de données. Cette utilisation demande une désactivation des interruptions et une maitrise parfaite de ce qu'on fait.
Les préfixes.
Dans les années 80, on a beaucoup parlé de préfixes étendus car les assembleurs de l'époque n'ont jamais été développés pour prendre en compte toutes les instructions du Z80. Cette situation perdure encore aujourd'hui et les assembleurs supportant les instructions étendues sont toujours rares (support partiel pour Winape et support complet pour Rasm et Sjasm) mais ils existent!
Ces préfixes étaient utilisés pour "débloquer" certaines fonctionnalités soit-disant cachées du Z80. En fait parfaitement documentées par Zilog au moment où ces assembleurs ont été créés.
Ainsi, pour adresser les 8 bits de poids faible de IX il fallait écrire
 DEFB #DD : LD L,5
Ce qui est équivalent à
 LD XL,5
Bien entendu la deuxième syntaxe est recommandée mais il faudra utiliser un assembleur moderne tel que Rasm ou Sjasm.
À propos des flags.
Cet ouvrage référence le comportement utile des flags après opération. Le comportement des bits 3 et 5 est beaucoup trop complexe pour être abordé dans un ouvrage de programmation. Ce comportement est néanmoins nécessaire à la programmation d'un émulateur Z80. Il faut savoir qu'il existe un registre interne au Z80, appelé MEMPTR ou WZ selon les documents disponibles et que ce registre est modifié par certaines instructions (incrémentation, recopie de BC ou PC, valeur de port ou de A, ...). Lorsque l'on utilise l'instruction BIT, les bits 11 et 13 de ce registre sont recopiés dans les bits 3 et 5 des flags. D'autres instructions réalisant des calculs recopient les bits de l'accumulateur dans ces fameux bits.
référence: https://baltazarstudios.com/webshare/A-Z80/memptr_eng.txt
Instructions de chargement de données.
LD.
L'instruction de base pour charger une valeur est LD (contraction de LOAD). Les instructions de chargement ne modifient jamais les flags.
On peut utiliser différente combinaisons de LD (cette liste est indicative)
 LD reg8,n ; charger une valeur immédiate 8 bits dans le registre 8 bits
 LD reg8,reg8 ; charger reg8 dans reg8
 LD A,(nn) ; charger la valeur stockée à l'adresse nn dans A
 LD A,(reg16)
 LD reg8,(HL) ;sauf XH,XL,YH,YL
 LD reg16,nn
 LD reg16,(nn)
 LD (nn),reg16
 LD (nn),A
 LD (reg16),A
 LD (HL),reg8 ;sauf XH,XL,YH,YL
Il n'est pas possible de charger un registre 16 bits dans un autre mais on peut utiliser presque toutes les combinaisons possibles avec les registres 8 bits. Ainsi, pour charger HL dans BC:
 LD H,B
 LD L,C
Il n'est pas possible d'effectuer des combinaisons de chargement LD reg8,reg8 entre les registres XH,XL et YH,YL et encore H,L car ils utilisent une racine commune d'opcode en interne. Les opcodes qui utilisent XH,XL,YH,YL sont préfixés par #DD ou #FD et suivis de l'opcode utilisé pour les registres H et L. Ce préfixe indique au Z80 de basculer sur les registres IX ou IY au lieu de HL.
Instructions d'échange de registres ou mémoire.
Le Z80 permet la permutation de certains registres, notamment pour accéder aux registres secondaires. Beaucoup de systèmes d'exploitation ont été conçus en n'utilisant qu'un seul des deux jeux de registre du Z80. Ainsi, l'utilisateur peut modifier les registres courants à loisir sans se soucier de les sauvegarder avant utilisation. Le système d'exploitation n'ayant qu'à exécuter un EXX pour retrouver "ses" registres.
EXX.
L'instruction EXX permute les registres BC, DE et HL avec les registres secondaires BC', DE' et HL'. L'instruction s'utilise sans paramètre. Pour rappel, les registres secondaires ne peuvent pas être accédés directement.
 EXX
EX.
L'instruction EX sert à échanger deux registres, ou un registre avec une valeur en mémoire. Les combinaisons suivantes sont:
 EX AF,AF' ; échange le registre AF avec le registre secondaire AF'
 EX HL,DE ; échange le registres HL avec le registre DE
 EX HL,(SP) ; échange le registre HL avec la dernière valeur stockée dans la pile
 EX IX,(SP) ; échange le registre IX avec la dernière valeur stockée dans la pile
 EX IY,(SP) ; échange le registre IY avec la dernière valeur stockée dans la pile
Instructions de comparaison.
CP.
L'instruction CP est en logique interne une soustraction du registre A qui ne met pas le registre A à jour. Seuls les flags sont positionnés en fonction du résultat de cette soustraction.
 CP reg8
 CP im8
 CP (hl)
 CP (ix+d)
 CP (iy+d)
Interprétation des flags (avec N qui est reg8, im8 ou (reg16) )
alternatives à CP.
Pour certaines comparaisons simples (-1, 0 ou 1) il est possible d'utiliser des instructions plus rapides dont l'usage premier n'est pas la comparaison
 OR A ; comparer A à zéro, ne modifie pas le registre
 DEC A ; Si A vaut 1 alors le flag Z sera positionné. Le registre A est modifié
 INC A ; Si A vaut 255 alors le flag Z sera positionné. Le registre A est modifié
comparaison 16 bits.
 OR A ; efface la retenue sans modifier le registre A
 SBC HL,DE ; Le registre HL est modifié par la soustraction avec retenue
Interprétation des flags
CPI.
Cette instruction est une instruction de comparaison groupée. L'instruction est équivalente au pseudo-code suivant:
 CP (HL) ; compare le registre A avec la valeur à l'adresse HL
 INC HL ; incrémente HL
 DEC BC ; décrémente BC
Si BC=0 après exécution de l'instruction, alors le flag P/V est mis à 0.
CPIR.
Cette instruction est une répétition de l'instruction CPI tant que BC est plus grand que zéro ou que le registre A est différente de la valeur pointée par HL. Par exemple, pour trouver la première occurrence de A en mémoire, on peut écrire.
 LD A,#55 ; chercher la valeur #55
 LD HL,montableau
 LD BC,1024 ; taille maximum du tableau
 CPIR
 DEC HL ; pour avoir l'adresse de l'occurrence, il faut décrémenter HL car il est incrémenté après chaque comparaison.
CPD.
Cette instruction est le pendant de l'instruction CPI mais avec une décrémentation de HL.
CPDR.
Cette instruction est le pendant de l'instruction CPIR mais avec une décrémentation de HL.
Instructions de saut non conditionnel.
sauts inconditionnels sans retour
JR.
Cette instruction permet d'effectuer un saut relatif, en avant ou en arrière avec une amplitude 8 bits, soit de -128 à 127. Il n'existe pas de version 16 bits de ce saut relatif. Certains assembleurs pourront automatiquement le remplacer par un saut 16 bits absolu mais comme le saut ne sera plus relatif, le code ne pourra s'exécuter correctement que de l'emplacement mémoire prévu à l'assemblage. Les autres assembleurs afficheront une erreur de saut relatif trop long.
 JR label
JP.
Cette instruction permet d'effectuer un saut absolu dans l'espace d'adressage 16 bits. On peut donner en argument un label ou des trois registres suivants: HL,IX,IY
 JP label
Attention, contrairement à ce que la syntaxe suivante suggère, on utilise bien la valeur du registre et non celle pointée par le registre!
 JP (HL)
 JP (IX) ; saute à l'adresse IX / Il n'est pas possible d'utiliser d'offset 8 bits avec cette instruction
 JP (IY) ; saute à l'adresse IY / Il n'est pas possible d'utiliser d'offset 8 bits avec cette instruction
CALL.
Cette instruction effectue un saut absolu dans l'espace d'adressage 16 bits. L'adresse de l'instruction suivante est enregistrée dans la pile. Ainsi le programme appelant peut revenir où il en était avec un RET.
RET.
L'instruction RET (abréviation de "return") effectue un saut à l'adresse lue et retirée du haut de la pile.
L'adresse aura été placée auparavant sur la pile typiquement par une instruction d'appel à une sous-routine.
 RET
sauts inconditionnels avec retour
Équivalentes à un appel de fonction, ces instructions de saut enregistrent dans la pile l'adresse d'appel.
Ainsi, le programme appelé peut retourner à l'appelant quand il se termine.
RST.
Cette instruction est un saut absolu spécifique qui ne peut s'utiliser qu'avec les adresses #00,#08,#10,#18,#20,#28,#30 ou #38. L'adresse de l'instruction suivante est enregistrée dans la pile. Ainsi le programme appelant peut revenir où il en était avec un RET.
Instructions de saut conditionnel.
Les sauts conditionnels n'effectuent le saut que si la condition est respectée.
sauts sans retour
JR.
 JR C,label ; saute si retenue (C flag = 1)
 JR NC,label ; saute si pas de retenue (C flag = 0)
 JR Z,label ; saute si zéro (Z flag = 1)
 JR NZ,label ; saute si non zéro (Z flag = 0)
JP.
 JP Z,label ; saute si zéro (Z flag = 1)
 JP NZ,label ; saute si non zéro (Z flag = 0)
 JP C,label ; saute si retenue (C flag = 1)
 JP NC,label ; saute si pas de retenue (C flag = 0)
 JP M,label ; saute si S flag = 1
 JP P,label ; saute si S flag = 0
 JP PE,label ; saute si P/V flag = 1
 JP PO,label ; saute si P/V flag = 0
DJNZ.
 DJNZ label ; décrémente B et saute si B est différent de zéro (ne modifie pas les flags)
RET.
Les instructions de retour de fonction sont des sauts sans retour.
 RET Z ; retourne à l'appelant si zéro (Z flag = 1)
 RET NZ ; retourne si non zéro (Z flag = 0)
 RET C ; retourne si retenue (C flag = 1)
 RET NC ; retourne si pas de retenue (C flag = 0)
 RET M ; retourne si S flag = 1
 RET P ; retourne si S flag = 0
 RET PE ; retourne si P/V flag = 1
 RET PO ; retourne si P/V flag = 0
sauts avec retour
CALL.
 CALL Z,label ; saute si zéro (Z flag = 1)
 CALL NZ,label ; saute si non zéro (Z flag = 0)
 CALL C,label ; saute si retenue (C flag = 1)
 CALL NC,label ; saute si pas de retenue (C flag = 0)
 CALL M,label ; saute si S flag = 1
 CALL P,label ; saute si S flag = 0
 CALL PE,label ; saute si P/V flag = 1
 CALL PO,label ; saute si P/V flag = 0
hack d'instruction: RST #38 conditionnel.
Il est possible de réaliser l'équivalent d'un RST Z,#38, d'un RST NZ,#38, d'un RST C,#38 ou enfin d'un RST NC,#38
En effet, l'opcode du RST #38 est #FF
On peut donc faire un RST Z,#38 (les syntaxes conditionnelles du RST #38 sont supportées par Rasm) en écrivant JR Z,$+1
Et par analogie, JR NZ,$+1 ou JR C,$+1 ou JR NC,$+1
Explications:
- Si la condition n'est pas remplie, on passe à l'instruction suivante (en 2 nops ou 7 cycles)
- Si la condition est remplie, on saute dans l'opcode lui même, sur la donnée qui permet de coder le saut relatif, ici #FF qui est l'opcode du RST #38
L'intérêt est évident, on est plus compact qu'un CALL Z,#38 et surtout beaucoup plus rapide!
Instructions de sauvegarde des registres dans la pile.
Lorsqu'on appelle une sous-routine, on peut avoir besoin de sauvegarder certains registres. Cette sauvegarde peut se faire indifféremment avant l'appel ou après l'appel même si la logique académique veut que ce soit l'appelé qui protège les registres qu'il va modifier.
PUSH.
 PUSH AF ; sauvegarde AF dans la pile pointée par SP et décrémente SP de 2
 PUSH BC ; ...
 PUSH DE
 PUSH HL
 PUSH IX
 PUSH IY
POP.
 POP AF ; récupère dans AF la valeur pointée par SP et incrémente SP de 2
 POP BC ; ...
 POP DE
 POP HL
 POP IX
 POP IY
Il n'est pas possible d'écrire ou de lire le registre de pile dans la pile. Mais on peut le faire de façon indirecte (voir chapitre programmation avancée).
 LD (spsav+1),SP ; écrire la valeur de SP dans le micro-code de l'instruction ci-dessous
 spsav LD HL,#1234 ; la valeur #1234 aura été remplacée par la valeur de SP
 PUSH HL ; donc PUSH SP
 POP HL ; récupère une valeur de la pile
 LD SP,HL ; et la copie dans SP, donc POP SP
Il existe des instructions pour le registre PC mais on leur a donné d'autres noms
 CALL $+3 ; équivalent à un PUSH PC pour enregistrer dans la pile l'adresse courante
 RET ; équivalent à un POP PC
pour aller plus loin.
Le Z80 ayant un bus de donnée 8 bits, il ne peut réaliser l'écriture ou la lecture mémoire 16 bits qu'en deux fois. Lors du PUSH, on descend dans la mémoire c'est donc logiquement l'octet de poids faible qui est écrit en premier, suivi de l'octet de poids fort. À l'opposé, lors d'une lecture mémoire 16 bits avec le POP, c'est l'octet de poids fort qui est lu en premier, suivi de l'octet de poids faible. Ceci peut avoir une incidence sur le matériel qui décode des valeurs 16 bits.
Instructions de modification de bit.
On peut tester, effacer ou positionner chaque bit individuellement d'un registre ou d'un octet en mémoire avec ces opérations.
SET.
L'instruction SET sert à positionner à 1 n'importe quel bit d'un registre ou d'un octet en mémoire.
 SET n,reg8 ; positionner un bit (sauf XH,XL,YH,YL)
 SET n,(reg16) ; positionner un bit (sauf BC,DE)
RES.
L'instruction RES (abréviation de "reset") sert à effacer n'importe quel bit d'un registre ou d'un octet en mémoire.
 RES n,reg8 ; effacer un bit (sauf XH,XL,YH,YL)
 RES n,(reg16) ; effacer un bit (sauf BC,DE)
BIT.
L'instruction BIT sert à tester n'importe quel bit d'un registre ou d'un octet en mémoire.
La valeur du bit est copié dans le flag Z, qui peut ensuite être utilisé dans une instruction conditionnelle.
 BIT n,reg8 ; tester un bit (sauf XH,XL,YH,YL)
 BIT n,(reg16) ; tester un bit (sauf BC,DE)
super instruction avec copie du résultat dans un autre registre.
Cette instruction possède un mode d'exécution qui copie le résultat dans un autre registre. La syntaxe a alors besoin de deux opérandes. Seuls les assembleurs Rasm et Sjasm les supportent.
Les combinaisons possibles de registres sont:
 BIT n,(IX+dep8),A
 BIT n,(IX+dep8),B
 BIT n,(IX+dep8),C
 BIT n,(IX+dep8),D
 BIT n,(IX+dep8),E
 BIT n,(IX+dep8),H
 BIT n,(IX+dep8),L
On retrouve les mêmes combinaisons pour le registre IY, les instructions SET et RES.
Instructions de décalage et rotations de bit.
Pour faciliter la navigation dans les instructions de décalage, voici un petit récapitulatif visuel des instructions de décalage les plus courantes.
De façon générale, toutes ces instructions modifient les flags de la façon suivante:
SLL (SL1).
Combinaisons possibles en mode simple:
 SLL A
 SLL B
 SLL C
 SLL D
 SLL E
 SLL H
 SLL L
 SLL (HL)
 SLL (IX+dep8)
 SLL (IY+dep8)
Combinaisons possibles en mode groupé:
 SLL (IX+dep8),A
 SLL (IX+dep8),B
 SLL (IX+dep8),C
 SLL (IX+dep8),D
 SLL (IX+dep8),E
 SLL (IX+dep8),H
 SLL (IX+dep8),L
 SLL (IY+dep8),A
 SLL (IY+dep8),B
 SLL (IY+dep8),C
 SLL (IY+dep8),D
 SLL (IY+dep8),E
 SLL (IY+dep8),H
 SLL (IY+dep8),L
RLD.
Ce décalage très particulier impacte le registre A ainsi que l'adresse pointée par HL.
Il effectue une rotation de 4 bits vers la gauche sur le nombre 12 bits composé des 4 bits de poids faible de A et de (HL).
 ; exemple 'visuel'
 LD A,#12
 LD (HL),#34
 RLD
 ; A=#13
 ; (HL)=#42
Les 4 bits supérieurs du registre A sont inchangés, il peut être nécessaire d'initialiser à zéro le registre avant usage.
Usage: Cette instruction trouve ses origines dans l'arithmétique BCD et permet par exemple de multiplier par 10 très facilement un nombre BCD de n'importe quelle taille. Comme elle modifie l'octet pointé par HL, il faut faire attention à son usage dans le cadre unique de la lecture.
Effet sur les flags:
RRD.
RRD est le pendant de l'instruction RLD. Il impacte le registre A ainsi que l'adresse pointée par HL.
Il effectue une rotation de 4 bits vers la droite sur le nombre 12 bits composé des 4 bits de poids faible de A et de (HL).
 ; exemple 'visuel'
 LD A,#12
 LD (HL),#34
 RRD
 ; A=#14
 ; (HL)=#23
Effet sur les flags:
Décalage 16 bits.
Il est possible de réaliser des décalages 16 bits vers la gauche de façon native en utilisant l'addition.
 ADD HL,HL ; copie le bit 15 dans C, décale tous les bits vers la gauche et injecte 0 dans le bit 0.
 ADC HL,HL ; copie le bit 15 dans C, décale tous les bits vers la gauche et injecte l'ancienne valeur de C dans le bit 0.
Pour faire un décalage équivalent à SLL il est nécessaire de décomposer
 SCF ; force la carry C
 ADC HL,HL ; décalage avec injection de C dans le bit 0
ou bien
 ADD HL,HL ; décalage des bits de HL
 SET 0,L ; forcer le bit 0 de HL
On peut réaliser des décalages 16 bits sur les autres registres, toujours en décomposant (exemples pour le registre DE):
SLA DE devient
 SLA E
 RL D
RL DE devient
 RL E
 RL D
SLL DE devient
 SLL E
 RL D
Instructions logiques de base.
Les opérations logiques de base concernent uniquement le registre A.
Il n'existe pas de version 16 bits de ces opérations.
AND.
Effectue un ET logique sur le registre A.
 AND A,reg8
 AND A,im8
 AND A,(reg16) ; sauf BC et DE
Rappel de la logique booléenne
 0 + 0 = 0
 0 + 1 = 0
 1 + 0 = 0
 1 + 1 = 1
OR.
Effectue un OU logique sur le registre A.
 OR A,reg8
 OR A,im8
 OR A,(reg16) ; sauf BC et DE
Rappel de la logique booléenne
 0 + 0 = 0
 0 + 1 = 1
 1 + 0 = 1
 1 + 1 = 1
XOR.
Effectue un OU exclusif logique sur le registre A.
 XOR A,reg8
 XOR A,im8
 XOR A,(reg16) ; sauf BC et DE
Rappel de la logique booléenne
 0 + 0 = 0
 0 + 1 = 1
 1 + 0 = 1
 1 + 1 = 0
CPL.
Effectue le complément à un du registre A (inverse tous les bits).
Rappel de la logique booléenne
 0 -> 1
 1 -> 0
NEG.
Le registre A devient A soustrait de zéro (inverse le signe mathématique).
SCF.
Cette instruction met à 1 le flag C et remet à zéro les flags H et N. Les autres flags ne sont pas modifiés.
CCF.
Cette instruction inverse les flags C et H. Le flag N est mis à zéro. Les autres flags ne sont pas modifiés.
Instruction de traitement des nombres en base 10.
DAA.
Cette instruction sert à ajuster la valeur d'un octet quand on s'en sert comme si il contenait deux chiffres décimaux. Les 4 bits du haut et les 4 bits du bas sont supposés contenir chacun une valeur de 0 à 9. Ainsi, quand on réalise des additions ou des soustractions, on appelle l'instruction DAA pour corriger les retenues à effectuer sur le registre.
Le fonctionnement de l'instruction est le suivant:
Quelques exemples d'exécution de l'instruction DAA:
La retenue (flag C) est mise dès lors qu'on dépasse la valeur 99. Il faut la reporter sur l'octet BCD suivant.
Instructions mathématiques de base.
INC.
Cette instruction incrémente le registre spécifié en opérande de 1.
 INC reg8 ; n'importe quel registre 8 bits sauf I, R et F
 INC reg16 ; n'importe quel registre 16 bits sauf AF
 INC (HL)
 INC (IX+n)
 INC (IY+n)
Effet de l'incrémentation 8 bits sur les flags
Effet de l'incrémentation 16 bits sur les flags
DEC.
Cette instruction décrémente le registre spécifié en opérande de 1.
 DEC reg8 ; n'importe quel registre 8 bits sauf I, R et F
 DEC reg16 ; n'importe quel registre 16 bits sauf AF
 DEC (HL)
 DEC (IX+n)
 DEC (IY+n)
Effet de la décrémentation 8 bits sur les flags
Effet de la décrémentation 16 bits sur les flags
ADD.
Cette instruction réalise une addition dont le résultat est stocké dans la première opérande. Les combinaisons possibles sont les suivantes:
 ADD A,im8
 ADD A,reg8
 ADD A,(reg16)
 ADD HL,HL ou BC ou DE ou SP
 ADD IX,BC ou DE ou IX ou SP
 ADD IY,BC ou DE ou IY ou SP
Effet sur les flags en addition 8 bits
Effet sur les flags en addition 16 bits
Attention: Comme l'addition se fait en interprétant les nombres négatifs comme des nombres positifs, la notion de débordement est toute relative. Ainsi, soustraire un nombre plus petit à un autre (en additionnant -100 à 101 par exemple) va positionner la retenue tandis qu'additionner -100 à 99 ne la positionnera pas. Quand on transpose les valeurs négatives en nombres positifs, le positionnement des flags fait sens.
Note
On peut écrire de façon raccourcie l'addition 8 bits sans mentionner le registre A
 ADD 5 ; équivalent à ADD A,5
 ADD B ; équivalent à ADD A,B
 ADD (HL); équivalent à ADD A,(HL)
SUB.
Cette instruction réalise une soustraction dont le résultat est stocké dans la première opérande. Le registre destination est toujours A. Les combinaisons possibles sont les suivantes:
 SUB A,im8
 SUB A,reg8
 SUB A,(reg16)
Effet sur les flags
Note On peut écrire de façon raccourcie la soustraction 8 bits sans mentionner le registre A
 SUB 5 ; équivalent à SUB A,5
 SUB D ; équivalent à SUB A,D
 SUB (HL) ; équivalent à SUB A,(HL)
ADC.
Cette instruction réalise une addition avec ajout de la retenue contenue dans le flag C. Le résultat est stocké dans la première opérande qui est soit A, soit HL. Les combinaisons possibles sont les suivantes:
 ADC A,im8
 ADC A,reg8
 ADC A,(reg16) ; sauf BC,DE,SP
 ADC HL,BC ou DE ou HL ou SP
Effet sur les flags
Note: On peut écrire de façon raccourcie l'addition 8 bits sans mentionner le registre A
 ADC 5 ; équivalent à ADC A,5
 ADC H ; équivalent à ADC A,H
 ADC (HL) ; équivalent à ADC A,(HL)
SBC.
Cette instruction réalise une soustraction en tenant compte de la retenue contenue dans le flag C. Le résultat est stocké dans la première opérande qui est soit A, soit HL. Les combinaisons possibles sont:
 SBC A,im8
 SBC A,reg8
 SBC A,(reg16) ; sauf BC,DE,SP
 SBC HL,BC ou DE ou HL ou SP
Effet sur les flags
Note: On peut écrire de façon raccourcie la soustraction 8 bits sans mentionner le registre A
 SBC 5 ; équivalent à SBC A,5
 SBC H ; équivalent à SBC A,H
 SBC (HL) ; équivalent à SBC A,(HL)
Instructions de copie mémoire.
Si il est possible de copier la mémoire à partir d'instructions simples, le Z80 offre plusieurs instructions de copie de blocs avec ou sans répétition. Ces super-instructions ont deux avantages:
LDI.
Cette instruction exécute la copie mémoire d'un octet de (HL) vers (DE), puis incrémente HL,DE et décrémente BC.
 LDI
LDIR.
Cette instruction exécute la copie mémoire de la même façon que LDI, tant que BC est supérieure à zéro.
 LD HL,source
 LD DE,destination
 LD BC,nombre
 LDIR ; copie BC octets depuis HL vers DE 
Le pseudo-code de cette instruction est le suivant:
 copymem
 LD A,(HL)
 LD (DE),A
 INC HL
 INC DE
 DEC BC
 JR NZ,copymem ; note:impossible à faire en vrai car DEC BC ne modifie pas les flags
LDD.
Cette instruction est similaire à LDI, si ce n'est que les pointeurs mémoire HL et DE sont décrémentés.
LDDR.
Cette instruction est similaire à LDIR, si ce n'est que les pointeurs mémoire HL et DE sont décrémentés.
Instructions d'entrée/sortie.
Il est possible de lire ou d'écrire sur un port mémoire. Cette section ne sera pas détaillée car les opérations d'entrée/sortie sont spécifiques au matériel avec lequel est connecté le Z80. Pour la petite anecdote, sur l'Amstrad CPC, les ingénieurs ont inversés les bits de poids fort avec les bits de poids faible du port d'entrée/sortie par économie, rendant inutilisables toutes les fonctions entrée/sortie de répétition qu'offre le Z80. Le processeur Z80 est conçu pour un design qui utilise le port pointé par le registre C alors qu'Amstrad a créé un design qui utilise le registre B pour pointer le port. Comme les instructions de répétition utilisent le registre B comme compteur, il faut pouvoir réajuster le registre B à chaque itération.
OUT.
Le OUT est l'instruction élémentaire pour envoyer une donnée sur un port I/O. Elle ne s'utilise qu'avec les registres 8 bits non spéciaux.
 OUT (C),A ; envoyer la valeur du registre A sur le port C
 OUT (C),B
 OUT (C),C
 OUT (C),D
 OUT (C),E
 OUT (C),H
 OUT (C),L
 OUT (C),0 ; envoyer zéro sur le port C
 OUT (im8),A ; envoyer A sur le port im8
OUTI.
Cette instruction est une instruction groupée d'envoi de donnée depuis le tableau pointé par HL avec une post-incrémentation.
 OUTI ; décrementer B*, envoyer la valeur de (HL) sur le port C, incrémenter HL
Il est important de noter que le registre B est décrémenté AVANT d'envoyer la valeur de (HL) sur le port comme on peut le lire dans beaucoup d'ouvrages. L'ordre a une importance car comme sur l'Amstrad le port de sortie est le port B, si on veut envoyer une valeur sur le port B, il faut la pré-incrémenter!
OTIR.
Cette instruction répète le OUTI tant que B est supérieur à zéro.
OUTD.
Cette instruction est une instruction groupée d'envoi de donnée depuis le tableau pointé par HL avec une post-décrémentation.
 OUTI ; décrementer B*, envoyer la valeur de (HL) sur le port C, décrémenter HL
Il est important de noter que le registre B est décrémenté AVANT d'envoyer la valeur de (HL) sur le port comme on peut le lire dans beaucoup d'ouvrages. L'ordre a une importance car comme sur l'Amstrad le port de sortie est le port B, si on veut envoyer une valeur sur le port B, il faut la pré-incrémenter!
OTDR.
Cette instruction répète le OUTD tant que B est supérieur à zéro.
IN.
C'est l'instruction élémentaire pour lire une valeur sur le port I/O. Elle ne s'utilise qu'avec les registres 8 bits non spéciaux.
 IN A,(C)
 IN B,(C)
 IN C,(C)
 IN D,(C)
 IN E,(C)
 IN H,(C)
 IN L,(C)
 IN 0,(C)
 IN A,(im8)
Les flags sont modifiés en fonction du résultat renvoyé:
INI.
Cette instruction est une instruction groupée de récupération de donnée vers le tableau pointé par HL avec une post-incrémentation.
 INI ; récupérer la valeur du port (C) et la mettre dans (HL), décrémenter B, incrémenter HL, positionner les flags HPNC au besoin
Instructions de gestion des interruptions.
DI.
Cette instruction (Disable Interruptions) désactive toutes les interruptions masquables.
EI.
Cette instruction (Enable Interruptions) active le déclenchement des interruptions après l'instruction suivante.
La précision à propos de l'instruction suivante est importante.
En effet, lorsqu'une routine appelée par interruption se termine, il faut autoriser à nouveau les interruptions (sinon elles ne se déclencheront plus).
Mais il est tout à fait possible que pendant le déroulement de la fonction sous interruption, une autre interruption soit survenue. L'interruption est donc en attente et se déclenchera dès lors que les interruptions seront à nouveau autorisées.
Nous avons vu que le déclenchement d'une interruption saute à une adresse définie par le mode d'interruption ET que l'adresse interrompue est enregistrée dans la pile.
Si l'autorisation des interruptions est immédiatement consécutive à l'instruction EI, il ne serait pas possible de revenir au programme interrompu avant qu'une interruption en attente se déclenche.
La conséquence serait un empilement d'adresses de retour dans la pile et un écrasement progressif de la mémoire, jusqu'à ce que la pile déborde sur la routine sous interruption.
C'est pour cette raison qu'après un EI, le Z80 exécute UNE instruction supplémentaire avant d'autoriser à nouveau les interruptions.
L'usage classique en retour d'interruption est le suivant :
 EI
 RET
IM.
Cette instruction (Interruption Mode) permet de choisir le mode d'interruption du Z80 parmi 3 modes.
Par défaut, le Z80 démarre en mode 1.
Mode 0
 IM 0
Ce mode de fonctionnement indique que les interruptions sont générées par un matériel externe.
Le Z80 exécute une instruction dont l'opcode aura été envoyé par le matériel sur le bus de données.
En théorie, l'instruction de saut serait un RST.
Ce mode a été très peu utilisé sur les ordinateurs.
Mode 1
 IM 1
Fonctionnement par défaut du Z80, le processeur exécute un saut à l'adresse #38.
Sur un Amstrad CPC, les interruptions sont générées par une puce vidéo tous les 300 de seconde (soit 52 lignes vidéo).
Sur un ZX Spectrum, les interruptions sont aussi générées en corrélation avec le contrôleur vidéo mais tous les 50 de seconde (fréquence de rafraîchissement à 50 Hz) lors de la VBL (synchro verticale : "Vertical BLanking).
Sur les calculatrices TI, le nombre d'interruptions dépend apparemment de l'état de la batterie (autour d'une centaine par seconde).
Mode 2
 IM 2
Le mode 2 est un mode d'interruption vectorisé.
Le Z80 récupère un numéro d'interruption sur le bus de données avec lequel il forme l'octet de poids faible d'une adresse.
L'octet de poids fort de l'adresse est contenu dans le registre I.
À l'adresse (toujours paire) pointée par la valeur 16 bits I<int>, le Z80 va lire une adresse 16 bits à laquelle il va sauter.
HALT.
Cette instruction boucle en continu jusqu'au déclenchement d'une interruption.
On se sert du HALT pour se synchroniser de façon précise sur une interruption.
Quand on n'utilise pas de HALT, le saut à l'interruption ne peut se faire qu'après la fin de l'exécution de l'instruction en cours.
Si cette instruction est longue, le déclenchement de l'interruption est retardé de quelques cycles d'horloge, ce qui peut être rédhibitoire si on a besoin d'une grande précision (typiquement programmation au vol de la puce vidéo).
RETI.
Cette instruction sert à acquitter les interruptions à des périphériques hardware en fin de routine.
Il est indispensable de précéder l'instruction avec EI pour que les interruptions puissent se déclencher à nouveau, sinon l'interruption de la carte matérielle restera masquée jusqu'au prochain EI.
En effet, le déclenchement d'une interruption (exceptée NMI) met le flag à 0 (les deux copies internes IFF1 et IFF2 du processeur), comme un appel explicite à l'instruction DI.
Un appel explicite à EI remet les deux copies IFF1 et IFF2 à 1, mais le processeur ne permettra une interruption qu'après l'instruction suivante (RETI dans ce cas) afin qu'une interruption n'empêche pas son exécution.
Dans le cas d'une NMI (Non Maskable Interrupt), seul le flag IFF1 est mis à 0.
La routine de traitement de cette interruption n'est pas obligée d'utiliser l'instruction EI, car les instructions RETN et RETI copient la valeur de IFF2 dans IFF1.
RETN.
Cette instruction sert à acquitter une interruption non masquable en fin de routine.
Tant que cette instruction n'est pas exécutée, les interruptions non masquables sont en attente.
RETN ou RETI ? Les deux instructions sont équivalentes.
Cependant, RETI est l'alias officiel reconnu par les périphériques pour détecter la fin de traitement d'une interruption.
Quand un périphérique voit passer le code de l'instruction RETI sur le bus de données, il sait qu'il peut retenter de déclencher une interruption.
LD I,A.
C'est la seule instruction qui permet de modifier le registre I.
Le registre I indique le poids fort de l'adresse de la table de saut à exécuter lors des interruptions en mode IM 2.
Instruction qui ne fait rien.
NOP.
Oui, il existe une instruction qui ne fait... ...rien! C'est l'instruction NOP pour No OPeration ou pas d'opération. En fait cette instruction peut jouer un rôle quand on a besoin d'une synchronisation précise. On ajoute des NOP pour créer un délai. Cette instruction ne modifie aucun registre (autre que PC qui passe à l'instruction suivante) et aucun flag. Son opcode #00 est simple à retenir.
Il existe d'autres opcodes qui ne font rien. Ce sont les opcodes non utilisés par le Z80. Comme ils ne sont pas décodés, le Z80 ne fera rien non plus mais ce genre d'utilisation est à éviter, pour préserver la compatibilité ascendante de versions plus évoluées du Z80.