CODINGCHRONIQUE Jean-Pierre Richard pour l'Ordinateur Individuel ★ Les opérations arithmétiques: de la multiplication aux entrées-sorties ★

L'Ordinateur individuel n°22 - Les opérations arithmétiques: de la multiplication aux entrées-sorties

Nous voici parvenus à la fin de cet exposé théorique sur le langage machine et l'assembleur pour le Z-80. Après avoir vu les« dernières » opérations disponibles, il ne vous restera plus qu'à pratiquer. Bon courage !

Multiplication et division en «binaire» seront étudiées après les opérations de décalage et de rotation.

Les instructions de comparaison du Z80 sont de deux types : comparaison simple ou recherche par comparaison.

L'opération de comparaison confronte le contenu de l'accumulateur (a) avec l'octet dans un registre r (r peut être B, C, D, E, H ou L) en effectuant la soustraction a-r. Le résultat modifie les indicateurs d'état C, Z, P/V et S. L'instruction CPr permet un test semblable au test du BASIC : A supérieur, égal, inférieur ou différent de r.

Les contenus de l'accumulateur et du registre ne sont pas modifiés par cette opération.

Le sous-programme présenté ci-dessous teste et dirige le programme principal vers SPRGR1 si A est égal à C (Z = 1 ) ou vers SPRGR2 si A est différent de C :

CP C ; A - C
JP Z, SPRGR1 ; si A = C vers sous programme 1
JP SPRGR2 ; si A ≠ C vers sous programme 2.

Cet autre petit sous-programme teste le registre D et branche le programme principal à l'adresse SPRGR3 si A est inférieur à D, à l'adresse SPRGR4 si A est égal à D ou à l'adresse SPRGR5 si A est supérieur à D.

CP D ; A - D
JP C, SPRGR3 ; A < D (C=1)
JP Z, SPRGR4 ; A = D (Z = 0)
JP SPRGR5 ; A > D si les deux tests précédents sont faux.

Les instructions de recherche par comparaison facilitent et diminuent le temps de recherche d'un octet dans un bloc de données. Le mode opératoire ressemble énormément à celui des instructions de transfert de blocs de données (LDI, LDD, LDIR et LDDR) : il faut initialiser les registres HL, BC et A avant d'effectuer l'opération de recherche.

Dans le cas des instructions CPI et CPIR, le registre pair BC contient le nombre d'emplacements mémoire affectés par la recherche (longueur du bloc). Le registre HL contient l'adresse basse du bloc et le registre accumulateur l'octet à rechercher.

L'instruction CPI compare le contenu de l'accumulateur avec l'octet contenu à l'adresse pointée par HL, puis incrémente HL et décrémente BC. L'indicateur Z est mis à 1 si l'octet contenu dans A est égal au contenu de l'adresse (HL).

L'instruction CPIR opère en suivant les mêmes étapes que l'instruction CPI, mais d'une façon répétitive. Cette répétition s'arrête quand l'octet est trouvé ou quand le compteur BC est égal à zéro. Si l'octet est trouvé, une instruction du type JPZ, SPRGR branchera le programme principal à un sous-programme «traitant». La première instruction de ce sous-programme devra décrémenter HL pour obtenir l'adresse exacte contenant l'octet.

Les instructions CPD et CPDR opèrent de la même façon que leurs « cousines » CPI et CPIR. Le registre pair HLdoit contenir l'adresse de fin de bloc, le registre pair BC le nombre d'octets à tester et l'accumulateur l'octet à rechercher. Cet octet est comparé au contenu de l'adresse pointée par HL; HL et BC sont décrémentés. Les étapes suivantes sont identiques à ce que nous avons vu précédemment.

Les opérations logiques diffèrent des opérations arithmétiques en opérant au niveau de chaque bit séparément et non au niveau de l'octet. Pour concrétiser le problème, nous avons illustré par des schémas électriques les opérations logiques suivantes : ET, OU et OU exclusif.

représentation utilisée :

Les instructions d'opérations logiques opèrent sur deux octets bit par bit. Un des deux octets se trouve dans l'accumulateur ; le résultat est consigné dans l'accumulateur.

L'instruction AND agit sur les indicateurs d'état S, Z et P/V. On a principalement recours à cette instruction pour masquer ou tester un bit dans un octet. L'opération de masquage d'un octet avec l'instruction AND met certains bits gênants à zéro Cette instruction teste également un bit dans un octet et affecte l'indicateur d'état Z; celui-ci sera soit égal à 1 si le bit est à l'état 0, soit égal à 0 si le bit est à l'état 1. AND 0FH ; masque le bit 5 6 et 7 de l'octet contenu dans l'accumulateur AND 08H ; si le bit 3 0, branchement vers SPR

JP Z,SPR ; si le bit 3 = 1 , instruction suivante.

L'instruction OR affecte également les indicateurs d'état S, Z et P/M. Sa principale utilité est de tester le contenu de l'accumulateur : la ligne de programme OR 0H met à 1 l'indicateur Z si A est égal à zéro. Les paires de registres seront testées de la façon suivante LD A, B ; premier octet dans l'accumulateur

OR C ; C + B si C et B sont nuls, alors Z = 1.

L'instruction XOR agit de la même façon sur les indicateurs S,Z et P/M. Cet ordre permet essentiellement la mise à zéro du contenu de l'accumulateur et de l'indicateur C de report. Son code machine correspond à un seul octet.

Les instructions d'opérations de rotation, de décalage et de manipulation (nombreuses dans la liste des instructions du Z 80) sont très puissantes. Il en existe 240, pas une de moins !

L'instruction SET 3,B met au niveau 1 le bit 3 de l'octet contenu dans le registre B
L'instruction RES 0,C met au niveau 0 le bit 0 de l'octet contenu dans le registre C.
L'instruction BIT 5, L teste le bit 5 du registre L et affecte l'indicateur d'état Z

Liste D : un programme de multiplication:

Nombreuses opérations de rotation, décalage et manipulation

Dans les exemples suivants le registre B contient l'octet 01110100

SET 0,B donne 01110101 (réinitialisation du registre B)
SET 2,B donne 01110100 (réinitialisation du registre B)
RES 0,B donne 01110100(réinitialisation du registre B)
RES 2,B donne 01110000 (réinitialisation du registre B)
BIT 0,B donne 01110100 (l'indicateur d'état Z est à 1)
BIT 2,B donne 01110100 (l'indicateur d'état Z est à 0)


Une multiplication en binaire

et maintenant une division

Étudions maintenant les opérations de rotation à l'aide d'exemples et de dessins appropriés :

D contient l'octet 11000010 et B l'octet 01000011

L'indicateur d'état est : C = 0

Remarque : avant l'étude de chaque cas. ces valeurs sont réinitialisées

La rotation circulaire à gauche RLC


RLC D donne la valeur 1 000 0101 et l'indicateur d'état est : C = 1.

RLC B donne la valeur 1 000 0110 et l'indicateur d'état est C = 0

La rotation circulaire à droite RRC.


RRC D dônne la valeur 0110 0001 et l'indicateur d'état est C = 0

RRC B donne la valeur 1010 0001 et l'indicateur d'état est C = 1

. La rotation à gauche RL

RL D donne la valeur 1000 0100 et C = 1 RL B donne la valeur 1000 0110 et C = 0.

La rotation à droite RR


RR D donne la valeur 0110 0001 et C = 0

RR B donne la valeur 0010 0001 et C = 1

Ne nous arrêtons pas en si bon chemin et voyons maintenant en quoi consistent les opérations de décalage et les instructions correspondantes. Les registres D et B, l'indicateur d'état C sont initialisés ou réinitialisés comme précédemment

. Le décalage arithmétique à gauche SLA

SLA D donne la valeur 1000 0100 (1 32 d) et l'indicateur d'état C est égal à 1

SLA B donne la valeur 1000 0110 (134 d) et C = 0.

Les valeurs binaires du contenu des registres D et B sont respectivement 194 et 67 en système décimal Le résultat obtenu après SLA B est le double de la valeur initiale (soit 134 décimal). Le résultat obtenu après SLA D n'est pas égal au double de la valeur initiale : il y a eu retenue (indicateur d'état C 1). Dans ce cas, le résultat est égal au double de la valeur initiale diminué de la valeur 256 (c'est-à-dire 132).

Le décalage arithmétique à droite SRA

Un mot d'explication : le registre est décalé vers la droite comme poussé par le bit 7 qui se trouve ainsi recopié.

SRA D donne la valeur 11100001 (-31 en représentation complément à deux) et C = 0.

SRA B donne la valeur 00100001 (33) et C = 0.

L'instruction SRA divise par deux le contenu d'un registre; le reste, s'il existe, se trouve dans l'indicateur d'état C.

Le décalage à droite logique SRL

SRL D donne la valeur 01100001 (97 d) et C = 0

SRL B donne la valeur 0010 0001 (33 d) et C = 1.

Cette instruction est différente de la précédente uniquement parce qu'elle divise par deux l'octet en représentation binaire simple.

Le registre, dans le cas d'opérations de décalages et de rotations, peut être le contenu d'une adresse pointée (HL) ou indexée (IX, IY). Le décalage à gauche d'un demi-octet (RLD) et la rotation à droite d'un demi-octet (RRD) sont utilisés lors de la représentation en binaire codé décimal (BCD). Nous avons fait volontairement l'impasse sur cette représentation... pas tous les plaisirs en même temps !

Il faut encore signaler quatre autres instructions de rotations sur l'accumulateur :

RLCA = RLC A
RRCA = RRC A
RLA = RL A
RRA = RR A

Ces instructions existent en double pour des problèmes de compatibilité de programme avec le microprocesseur 8080. Elles sont tout de même utilisées dans les programmes de Z80 car leurs codes machine sont en un seul octet.

Maintenant que nous avons passé en revue toutes les instructions de décalage et de rotations, revenons aux opérations arithmétiques avec l'étude de la multiplication et de la division.

La multiplication binaire suit le mode opératoire d'une multiplication décimale. Effectuons par exemple une multiplication dont le multiplicande est 00000101 (5 d.) et le multiplicateur 0000 0101 (5 d):

00000101 (5 d.)
x 00000101 (5 d.)
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
00000101
00000000
00000101
00000000...
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
00000011001 (25 d.)

La division binaire n'est pas plus compliquée. Jugez-en vous-mêmes : prenons un exemple où le diviseur est 0000 1000 ( 8 d.) et le dividende 0101 0111 (87 d ):

Le quotient est la juxtaposition successive de bits 1 quand le diviseur « va » et de 0 quand le diviseur ne va pas. Ici le quotient obtenu est 1010. Si l'on ne peut plus «abaisser», la division est terminée. Cela donne le reste, 1 11 dans le cas présent Voir l'organigramme général d'une division en binaire page précédente.

Les opérations d'entrée / sortie sont spécifiques

Les instructions d'opérations d'entrées et de sorties permettent l'échange de données avec le « monde extérieur ». Ces « extra-mu-ros », appelés périphériques, peuvent être un clavier ASCII, un écran, un magnétophone, une imprimante, un capteur d'information (pression, température, contrôle d'un système...) ou un relais (asservissement d'une machine).

La rapidité des opérations d'entrées et de sorties de données entre le microprocesseur et l'extérieur dépend du mode de transfert de bits dans le bus : le bus parallèle transfère les données « de front ». Le raccordement avec un périphérique demande au minimum huit fils (S100, IEEE 488, IEEE 588). Le bus sériel transfère les données bit par bit. Le raccordement avec un périphérique demande un seul fil (deux en réalité pour des programmes d'adressage) pour le transfert des données

L'instruction de base pour les entrées de données est INA, (n). Une autre instruction, INR, (C), permet de charger le registre R (A, B, C, D, E. H ou L) d'un octet provenant du port entrée/sortie pointé par le registre C.

L'instruction INI permet l'entrée d'une donnée en mémoire ; pour cela, le registre HLdoit contenir l'adresse du début de bloc à charger, le registre B le nombre de données à traiter et le registre C l'adresse du port.

Le déroulement de l'opération s'effectue de la manière suivante : la donnée transmise par le périphérique est copiée dans la mémoire pointée par HL. HL est incrémenté et le compteur B décrémenté L'instruction INIR effectue les mêmes opérations de façon répétitive. Les instructions IND et INDR sont très voisines des précédentes: H L pointera l'adresse haute du bloc et, dans le déroulement des opérations, HL sera décrémenté.

Liste E : une division binaire 16 bits par 8 bits:

L'instruction de base correspondant à la sortie de données est OUT (n), A. Parallèlement à INR,(C) il existe une instruction OUT (C), R Les instructions OUTI, OTIR, OUTD et OTDR agissent de la même manière que les instructions INI, INIR, IND et INDR ; dans ce cas les données sont transmises à un périphérique L'étude de ces instructions à l'aide d'exemples de programmes est fonction des adresses et de la structure des ports d'entrées et de sorties elle dépend donc de l'ordinateur utilisé.

Dans le cas du TRS 80, l'adresse du port Cassette est 0FFH ; la structure du port est la suivante

LD C,0FFH ; port E/S magnéto (TRS 80)
LD B.8 ; soit 0000 1000
OUT (C),B ; met en 32 caractères/ligne
LD A,4 ; soit 00000100
OUT 0FFH,A ; le relais du magnéto est collé

Les instructions de gestion des interruptions régissent les priorités d'intervention des circuits périphériques. Si l'interruption est autorisée (EI), le microprocesseur branche le programme, quelle que soit sa position, vers un sous-programme dit « de service ». Quand ce sous-programme est exécuté, le microprocesseur redonne le contrôle au programme principal à l'endroit où l'interruption a eu lieu. L'instruction Dl interdit les interruptions

Et voilà ! nous sommes arrivés au terme de notre série d'articles sur l'assembleur.

Les notions exposées n'ont pas la prétention d'être exhaustives mais peut-être vous auront-elles donné l'envie d'en savoir plus.

« Le difficile, c'est ce qui peut être fait tout de suite; l'impossible, ce qui prend un peu plus de temps ». (G. Santayana).

Jean-Pierre Richard, L'Ordinateur individuel n°22

★ REVUE: L'Ordinateur Individuel
★ ANNÉE: ???
★ AUTEUR: Jean-Pierre RICHARD

Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.732-desktop/c
Page créée en 614 millisecondes et consultée 135 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.