Programmation Assembleur Z80

Un livre de Wikilivres.
Aller à : navigation, rechercher
Programmation Assembleur
Modifier ce modèle
Retour au livre Programmation

Introduction

L'assembleur, pour le Z80 comme tous les processeurs, est le langage de plus bas niveau de programmation et donc le plus rapide.
Rappelons que ce processeur est fabriqué par Zilog, est cadencé à 8 MHz en utilisation normale et est un processeur 16 bits interne et 8 bits externe. Il a été commercialisé dès 1976, mais on le trouve encore aujourd'hui dans les calculatrices TI-84 et TI-84+. Le Z80 est compatible avec le 8080 de Intel, et on trouve aujourd'hui un processeur compatible, le Z180, avec quelques instructions supplémentaires.

Les registres

Le Z80 contient 22 registres dont certains de 8 bits peuvent être associés par deux pour former un registre de 16 bits. D'autres sont toujours des registres 16 bits (IX):
A, F, B, C, D, E, H, L, IX, IY, SP, PC, I et R ainsi que les registre alternatif A', F', B', C', D', E', H', L'.
Les lettres simples sont des registres 8 bits et les lettres doubles 16 bits.
On peut faire aussi ces associations et seulement celles-ci:
AF, BC, DE, et HL (ainsi que leur registre supplementaire).
Les registres alternatif ne sont pas accessible directement, il faut passer d'une page de registre à l'autre grâce aux instructions EX AF,AF' pour échanger A et F par A' et F', et EXX pour l'échange des registres BC, DE, HL. Ceci permet par exemple les interuptions rapide, cette méthode étant plus rapide qu'une sauvegarde dans la pile.

Le registre A est l'accumulateur, BC et DE sont utilisés comme "tampons" pour les données temporaires, HL est surtout utilisé pour transférer des données dans la mémoire RAM (Random Access Memory).
F est le registre contenant les "Flags" (drapeaux en anglais): il contient entre autres les résultats des opérations.
IX et IY sont les index.
SP (stack pointer) est l'adresse du haut de la pile de donnée et d'appels dans la RAM.
PC (program counter) est l'adresse de l'instruction en cours d'exécution. R est le registre refresh.
I est utilisé pour les interruptions dans certains modes

En règles générales on utilise surtout A,BC,DE,HL en programmation car très peu d'opérations sont possibles sur les autres registres.


Stocker des valeurs dans les registres

Pour stocker des valeurs dans les registres, rien de plus simple:
Il faut utiliser l'instruction LD (contraction de LOAD).
Si on veut stocker , par exemple, la valeur 17 dans la registre A:

  LD A, 17      ;17 est ici noté en décimal

Mais on peut aussi le noter en hexadécimal:

  LD A, $11     ;17 est ici noté en hexadécimal

Cela donne au registre A la valeur 17.
Attention, ce registre est un registre 8 bits qui limite la valeur à 255 en décimal, soit $FF en hexadécimal. Les nombres décimaux et négatifs ne peuvent pas non plus être traités de cette façon.
Nous pouvons faire la même chose avec un autre registre et une autre valeur:

  LD B, 32
LD C, $18
LD H, %01001010 ;ici le nombre est noté en binaire: 01001010b = 74d

On peut faire de même avec un registre pair:

  LD BC, 14238   ;ici les valeurs sont en 16 bits
LD HL, $80DF

Attention les nombres sont ici limités à 65535d.

Une autre façon d'utiliser LD est de charger une donnée d'un registre vers un autre:

  LD B, A

Cela met la valeur du registre A dans le registre B. Comme vous pouvez le voir, dans n'importe quelle utilisation de LD, la donnée est déplacée de la droite vers la gauche. On peut charger un simple registre dans un autre registre.
Attention: on peut charger un registre 8 bits dans un de 16 bits, mais pas l'inverse! Par exemple:

  LD HL,A
/!\ LD A,HL est interdit!

Des utilisations plus compliquées de LD (mais très utiles) impliquent de déplacer des données entre la mémoire (RAM) et les registres. Comme vous le savez, on accède à la mémoire par des adresses. L’instruction LD est utilisée pour charger une donnée entre un registre et une zone mémoire spécifiée par une adresse. Cette adresse peut être une valeur brute:
LD HL, ($80DF)
Ceci charge la valeur enregistrée dans la zone mémoire d’adresse $80DF et la stocke dans le registre HL. Les parenthèses autour du nombre indique que le nombre est utilisé comme une adresse, et non comme une valeur.

Dans l’exemple précédent, nous avons chargé un certain registre à partir d’une adresse spécifique de la mémoire, et avons utilisé le registre HL. Cela signifie que nous ne pouvons pas charger n’importe quel autre registre directement de la mémoire. Pour charger un autre registre, nous chargeons la mémoire dans HL puis l’autre registre avec HL:

  LD HL, ($80DF)
LD BC, HL n'existe pas, il faut utiliser:
LD B,H
LD C,L

Opérations logiques et mathématiques

Il est possible de modifier la valeur d'un registre avec des opérations. La plupart de ces opérations, cependant, affectent seulement le registre A. Les instructions a utiliser sont ADC, ADD, AND, DEC, INC, NEG, OR, RL, RR, SBC, SUB, et XOR. Les instructions AND, OR, et XOR ne peuvent être appliquées qu'au registre A. leur syntaxe est:

AND valeur
OR valeur
XOR valeur

où valeur peut être un registre où une valeur directe (comme 23). Ce sont des opérateurs logiques binaires, AND réalise un ET logique de la valeur donnée avec le registre A dans lequel il va stocker le résultat. OR effectue de la même façon un OU logique inclusif. et XOR un OU exclusif. Par exemple:

LD A,32
OR 16

va donner à A la valeur 48, car si on écrit l'opération en binaire:

00100000 =32
00010000 =16
-------- OU
00110000 =48

Les flags

Les flags sont stockés dans le registre F. Ils sont modifiés par la plupart des instructions et permettent de réaliser principalement des sauts conditionnels.

Si la dernière opération effectuée a donné un résultat nul, alors le flag Z sera actif. Dans le cas contraire, le flag NZ sera actif. S'il y a eu un débordement (le résultat d'une opération est un nombre négatif, ou plus grand que la valeur maxmale que le registre peut contenir), alors le flag C sera actif, et NC est le flag contraire, activé donc s'il n'y a pas eu de débordement.

Tableau récapitulatif de l'effet des instructions assembleur Z80 sur les flags

Instruction S Z PV C Instruction S Z PV C
ADC reg,reg  ?  ?  ?  ? LDD . .  ? .
ADD A,reg  ?  ?  ?  ? LDDR . . 0 .
ADD autre . . .  ? LDI . .  ? .
AND reg  ?  ?  ? 0 LDIR . . 0 .
BIT reg,reg  ?  ?  ? . NEG . . . .
CALL . . . . NOP . . . .
CCF . . .  ? OR  ?  ?  ? 0
CP reg  ?  ?  ?  ? OTDR  ?  ?  ? .
CPD  ?  ?  ? . OTIR  ?  ?  ? .
CPDR  ?  ?  ? . OUT reg,reg . . . .
CPI  ?  ?  ? . OUTD  ?  ?  ? .
CPIR  ?  ?  ? . OUTI  ?  ?  ? .
CPL . . . . POP reg . . . .
DAA  ?  ?  ? . PUSH reg . . . .
DEC reg16 . . . . RES reg,reg . . . .
DEC autre  ?  ?  ? . RET . . . .
DI . . . . RL  ?  ?  ?  ?
DJNZ . . . . RLA . . .  ?
EI . . . . RLC reg  ?  ?  ?  ?
EX reg,reg . . . . RLCA . . .  ?
EXX . . . . RLD  ?  ?  ? .
HALT . . . . RR reg  ?  ?  ?  ?
IM reg . . . . RRA . . .  ?
IN reg,reg  ?  ?  ? . RRC reg  ?  ?  ?  ?
INC reg16 . . . . RRCA . . .  ?
INC autre  ?  ?  ? . RRD  ?  ?  ? .
IND  ?  ?  ? . RST reg . . . .
INDR  ?  ?  ? . SBC reg,reg  ?  ?  ?  ?
INI  ?  ?  ? . SCF . . . 1
INIR  ?  ?  ? . SET reg,reg . . . .
JP reg . . . . SLA  ?  ?  ?  ?
JR reg . . . . SRA  ?  ?  ?  ?
LD A,I  ?  ?  ? . SRL  ?  ?  ?  ?
LD A,R  ?  ?  ? . SUB  ?  ?  ?  ?
LD autre . . . . XOR  ?  ?  ? 0

? indique que le flag peut être modifié dans certains cas,
. indique que le flag n'est jamais modifié,
0 ou 1 indique que le flag prend toujours cette valeur.

Wikipedia-logo-v2.svg

Wikipédia propose un article sur : « Z80 ».