CODING ★ Dr.Watson - Autoformation à l'assembleur par Micro Application ★

Dr.Watson - Autoformation à l'assembleur par Micro Application - Chapitre 04

CHAPITRE 4

OPERATIONS ARITHMETIQUES

La plus part des situations réelles demandent la manipulation de nombres. Jusqu'ici, nous pouvons seulement incrémenter et décrémenter le contenu des registres ou des cases mémoire. Le Z80 nous fournit quelques Instructions arithmétiques supplémentaires, oui, bien que peu étendues, forment les bases d'opérations plus puissantes.

Ce chapitre explique ces instructions. Si vous n'êtes pas familiarisé avec les représentations binaire ou hexadécimale des nombres, reportez-vous à l'appendice 5 et travaillez-le.

Les concepts binaire et hexadécimal vous sont maintenant familiers. Vous verrez bientôt pourquoi nous utilisons les nombres hexadécimaux, cela évite au moins du travail de frappe !

Nous pouvons classer les instructions arithmétiques en deux groupes, le groupe 8 bits et le groupe 16 bits. Dans ce chapitre nous nous occuperons principalement du groupe 8 bits, puis nous verrons ultérieurement le groupe 16 bits.

Le procédé arithmétique le plus commun est l'addition de deux nombres. Pour additionner entre eux deux nombres à 8 bits, l'instruction suivante est utilisée:

ADD A,n Ajouter (ADD) n au contenu de l'accumulateur, en remplaçant le contenu de

; l'accumulateur par le résultat.

Pour illustrer cette commande nous ajouterons 65 à 20, ce qui donne 85. Quand le résultat sera affiché sur l'écran, nous verrons un U. (Le caractère correspondant à la valeur ASCII de 85).

Essayez le programme suivant

PROGRAMME 4.1

ENT

LD A,65 ;Charger 65 dans A

ADD A,20 Ajouter 20 à A

CALL 47962 Afficher le résultat sur l'écran

RET

Vous voyez qu'un U apparaît sur l'écran.

L'assembleur permet aussi la représentation hexadécimale des nombres. Pour permettre à l'assembleur de les reconnaître, les nombres hexadécimaux sont précédés d'un '&'.

Réécrivez le programme 4.1 en utilisant la représentation hexadécimale pour 47962, 65 et 20 :

PROGRAMME 4.2

ENT

LD A, &41

ADD A,&14

CALL &BB5A

RET

Vérifiez que ce programme est bien le même que le programme 4.1 lorsque vous le lancez.

EXERCICE 4.1

Ecrivez un programme qui ajoutera 200 a 48 puis affichera le résultat sur l'écran.

Une réponse possible est donnée dans le chapitre solutions.

EXERCICE 4.2

Ecrivez un programme qui ajoutera &41 à &10. Puis affichera le résultat sur l'écran. Qu'est-ce qui sera affiché ?

Une réponse possible est donnée dans le chapitre solutions.

Jusque là toutes nos réponses ont été inférieures à 255, le nombre maximum de 8 bits qu'un registre puisse contenir. Que pensez-vous qu'il arrive si 150 et 171 sont additionnés? Essayez le programme suivant. N'oubliez pas ENT.

PROGRAMME 4.3

LD A,150 ;Charger 150 dans A

ADD A, 171 Ajouter 171 à A

CALL 17962 Afficher le résultat sur l'écran

RET

Ce qui s'est passé, c'est que l'accumulateur a débordé. Il a atteint 255 puis lorsque 1 de plus a été ajouté, il est revenu à zéro et a recommencé, atteignant 65; d'où le A sur l'écran.

Ce que l'on ne peut pas voir d'après le programme, ce sont les registres de flags. Si cela était visible, nous aurions pu voir que lorsque l'accumulateur a débordé, le bit de retenue a été mis (1). Ceci peut âtre utilisé pour additionner deux nombres dont la somme est supérieure a 255. Nous i1 lustrerons d'abord ce procédé sur le papier, puis nous écrirons un programme qui accomplira la même tâche en langage assembleur.

Problème : Ajoutez 1157 à lui même, soit 1157 + 1157 = ?

Convertissez 1157 en hexadécimal.

1157 : 1096 = 0 reste 1157

1157 : 256 = 1 reste 133

133 : 16 = 8 reste 5

5 : 1 = 5 reste 0

Donc : 1157 = &0485

&0485 exprimé en binaire est un nombre a 16 bits. Il faut donc qu'il soit partagé en deux pour permettre l'utilisation d'instructions arithmétiques a 8 bits. C'est facile en hexadécimal. (Voila pourquoi on utilise la représentation en hexadécimal!)

----- ------ Octet fort = &04

! 04 ! ! 85 ! !

----- ------ !

! !----------

!-------------------Octet faible = &85

ETAPE 2

Pour additionner entre eux les deux &0485 il nous faut d'abord additionner les octets faibles puis les octets forts, en tenant compte de toute retenue générée par l'addition des octets faibles.

; 85 85

;+85 ;+85

; -- ;----

+ retenue OA +retenue 6 10 Décimal

; +retenue 0 A Hexadécimal

Le résultat est donc &0A + une retenue

ETAPE 3

Additionnez les octets forts entre eux en tenant compte du bit de retenue.

04

+04

--

08

--

Maintenant ajoutez le bit de retenue :

01 + 08

--

09

--

ETAPE 4

Recombinez le nouvel octet faible et le nouvel octet fort.

1157 + 1157 = &090A

Puis vérifiez vous-même que &090A égale 2314.

La caractéristique principale à noter est que dans tout travail en DOUBLE PRECISION, c'est à dire avec l'utilisation de nombres à 16 bits, on agit d'abord sur l'octet faible, de façon à tenir compte de la retenue (s'il y en a une) .

Avant de pouvoir écrire le programme pour faire cette addition, il nous faut connaître quelques nouvelles instructions :

AND A ET logique de l'accumulateur.

Un seul effet de cette opération doit être observé pour le moment, c'est la remise a zéro du flag de retenue. Pourquoi est-ce nécessaire ? Réponse: Si le flag de retenue était mis de façon non intentionnelle, le résultat après l'addition serait incorrect a cause de l'inclusion de la retenue incorrecte dans l'addition.

Une instruction qui additionne deux registres plus le contenu du flag de retenue est à présent requise.

ADC A,s Ajoute le contenu du registre s plus le flag de retenue au

;contenu de l'Accumulateur. Le résultat est stocké dans

;l'accumulateur.

Remarquez que l'instruction ADC utilise un registre comme l'un de ses opérandes. Une instruction similaire à ADD A,n existe, il faut utiliser un registre à la place de la donnée immédiate n.

ADD A,s Ajouter le contenu du registre s au contenu de l'Accumulateur.

; Le résultat est stocké dans l'accumulateur.

Maintenant, le programme.

PROGRAMME 4,4 (ne l'assemblez pas encore)

LD C,&85 ; Charge dans C le 1er octet faible

LD A,&85 ; Charge dans A le 2ème octet faible

AND A ; Annule le flag de retenue

ADD A,C ;A = octet faible + octet faible

LD (87000),A Sauvegarde le nouvel octet faible

LD C,804 ; Charge dans C le 1er octet fort

LD A, 804 ;Charge dans A le 2ème octet fort

ADC A,C ;A = octet fort + octet fort + retenue

LD (87001),A Sauvegarde le nouvel octet fort

Bon, ce programme additionne deux nombres. Mais comment vérifier le résultat ?

Ce qu'il nous faut maintenant, c'est un programme pour afficher la réponse dans un format reconnaissable. Pourquoi les contenus des deux cases mémoire ne peuvent-ils être affichés sur l'écran ? Rien de reconnaissable n'apparaîtrait, puisque les codes ASCII &09 et &0A ne représentent pas des caractères mais des codes de contrôle. Un décalage doit être ajouté aux deux réponses pour les amener dans le cadre de l'alphabet ASCII (65-122).

Comme le code de A est 65, cela paraît un décalage raisonnable à utiliser. Donc nous ajoutons les lignes suivantes au programme initial là où nous l'avons laissé:

PROGRAMME 4.4 (a)

LD C,65

LD A,(&7001)

ADD A,C

CALL &BB5A

LD A,(&7000)

ADD A,C

CALL &BB5A

RET

A présent assemblez et lancez tout le programme. Vous verrez un J et un K sur l'écran (correspondant à &09 + 65 et 804 + 65).

EXERCICE 4.3

Ecrivez un programme pour additionner 250 à 600, en hexadécimal, en ajoutant 65 aux octets fort et faible. Puis affichez le résultat sur l'écran.

Une réponse possible est donnée dans le chapitre solutions.

SOUSTRACTION

SUB s ;Soustrait (SUBtracts) le contenu du registre s de l'accumulateur.

; Le résultat est stocké dans l'accumulateur.

SBC A,s Soustrait le contenu du registre s plus le flag de retenue, de

;l'Accumulateur. Le résultat est stocké dans l'accumulateur.

L'opération de soustraction de deux nombres à 8 bits est laissé pour l'exercice 4.4. Essayez !

EXERCICE 4.4

Ecrivez un programme qui soustraira 9 de 233. Affichez le résultat sur l'écran. Remarquez qu'il n'est pas nécessaire d'ajouter un décalage de 65 pour le résultat. Pourquoi ?

Une réponse possible est donnée dans le chapitre solutions.

EXERCICE 4.5

Ecrivez un programme qui calculera le résultat de la somme suivante :

(97 + 126) - 153 = ?

Une réponse possible est donnée dans le chapitre solutions.

Comme nous l'avons vu précédemment, lors de l'addition de deux nombre: donnant un résultat supérieur à 255, un dépassement se produit. Ce dépassement fait que le flag de retenue est mis.

La situation opposée se produit lorsque l'on essaie de soustraire un grand nombre d'un petit nombre. Par exemple, essayez cela :

25 - 17

Il n'est pas possible de soustraire directement 7 de 5, alors on emprunte une unité de la colonne suivante. La première étape de la soustraction devient alors :

5 + emprunt= 15

- 7 ; - 7

-- ; --

? ; 8 Rép1=8

Puisque nous avons emprunté, il nous faut rembourser : soit soustraire 1 de la colonne suivante,

Nous complétons la soustraction.

2 - emprunt = 1

- 1 ; - 1

-- ; --

? ; 0 Rép2=0

-- ; --

Nous combinons les deux réponses (Rép1 et Rép2)

0 + 8 = 8

Donc:

27-17 = 8

En utilisant le même procédé, nous pouvons accomplir cette soustraction avec les instructions de soustraction du Z80.

Problème : Soustrayez 2000 de 2224.

ETAPE 1

Convertissez les deux nombres en hexadécimal.

2000 : 4096 = 0 reste 2000

2000 : 256 = 7 ;reste 208

208 : 16 = D reste 0

0 : 1 = 0

2224 : 4096 = 0 reste 2224

2224 : 256 = 8 reste 176

176 : 16 = B reste 0

0 : 1 = 0

2000 = &07DO

2224 = &08B0

ETAPE 2

Soustrayez les deux octets faibles

B0 + emprunt = 1B0

-D0 ; D0

-- ; --

?? ;-- E0

-- ;! --

; ! !-- 0=0-0

; !-E=1B-D

ETAPE 3

Puis les octets forts

08 08

-07 - 07 + emprunt = 08

-- --

?? 00

-- --

Combinez les deux résultats :

2224-2000 = &00EO

Lorsque l'on fait ce type de soustraction, le flag de retenue agit un flag d'emprunt, qui est mis lors de l'apparition d'un emprunt. Convertissons maintenant cette soustraction en instructions Z80.

PROGRAMME 4.5

LD C,&D0 C= 1er octet faible

LD A,&B0 A= 2eme octet faible Annule

AND A ;Annule le flag de retenue

SUB C ;A= nouvel octet faible

LD (&7000),A Sauvegarde octet faible

LD C,&07 C= 1er octet fort

LD A,&08 A= 2eme octet fort

SBC A,C ;A= A-C-retenue

LD (&7001),A Sauvegarde octet fort

LD A,(&7000) Rappelle octet faible

CALL &BB5A Affiche résultat

RET

Points à noter : premièrement, comme l'octet fort de la réponse est connu comme étant zéro, ce n'est pas la peine de l'afficher. Deuxièmement, ce n'est pas la peine d'ajouter un décalage à la réponse puisqu'elle est dans le cadre affichable des caractères ASCII (65-255).

EXERCICE 4.6

Ecrivez un programme pour faire une soustraction à 16 bits en utilisant les instructions suivantes ( ss est un registre double -ici : BC ou DE)

SBC HL,ss

Par exemple : 4248 - 4008 = ?

(Indication = c'est plus facile que le programme 4.5) Réponse dans le chapitre solutions

EXERCICE 4.7

Stockez deux nombres en mémoire, puis ajoutez a ceux-ci le contenu de l'accumulateur. Remplacez les anciennes valeurs par les résultats nouvellement calculés.

Les tables suivantes vous aideront.

-----------------------------

! Case ! Contenu !

! mémoire ! ; !

-----------------------------

! 35000 ! 10 !

! 35001 ! 20 !

-----------------------------

Accumulateur = 65

Après exécution du programme,

----------------------------------

! Case ! Contenu !

! mémoire ! ;!

! 35000 ! 75 !

! 35001 ! 85 !

----------------------------------

Utilisez l'instruction ADD A,(HL). Vérifiez que les résultats sont ceux espérés en affichant le contenu de la case mémoire sur l'écran.

Réponse au chapitre solutions.

EXERCICE 4.8

Tracez sur l'écran une ligne jusqu'au point 100,50 en utilisant la routine de tracement de ligne. Puis ajoutez 75 à chaque coordonnée et tracez une autre ligne jusqu'à ce point.

La routine de tracement de ligne est entièrement détaillée dans l'annexe approprié, mais nous vous indiquons brièvement :

Appeler adresse 48118

Paramètres X,Y

X passé en DE

Y passé en KL

Une réponse possible est donnée au chapitre solutions.

Hé bien, tout cela apporte une conclusion aux principes de base de l'addition et de la soustraction. Bien que non mentionnées explicitement, les instructions suivantes devraient pouvoir être comprises aisément :

-----------------------------------------

! Instructions ! Opération symbolique !

-----------------------------------------

! ADD HL,SS ! HL ! ADC HL,SS ! HL ! SBC HL,SS ! HL ! ADD IX,pp ! IX ! ADD IY,rr ! IY -----------------------------------------

Ici ss est BC, DE, HL ou SP,

pp est BC, DE, IX ou SP,

rr est BC, DE, IY ou SP

D'après l'opération symbolique, vous devriez pouvoir comprendre ce que chaque instruction accomplit. Il est possible d'additionner ou de soustraire des nombres à 32 bits en utilisant les instructions ci-dessus et le flag de retenue, en utilisant la même méthode que pour l'arithmétique à 16 bits réalisée avec des instructions à 8 bits.

LES INSTRUCTIONS DE FLAG DE RETENUE

Avant toute opération arithmétique, le flag de retenue doit être annulé. Cela se fait en utilisant l'instruction AND A. Le flag de retenue peut également être annulé en utilisant les deux instructions suivantes :

SCF Met le flag de retenue

CCF Inverse le flag de retenue

Pour annuler le flag de retenue avec ces instructions, le flag de retenue est d'abord mis en utilisant l'instruction SCF, puis il est inversé par l'instruction CCF. Lorsqu'un nombre binaire est inversé, un zéro est remplacé par un un; de la même manière un un est remplacé par un zéro. Le flag de retenue lorsqu'il est mis, est égal à un, et donc après inversion, il sera égal a zéro. La raison de l'utilisation de AND A est que cela demande moitié moins de temps que SCF et CCF.

RESUME

Les principes de bases de l'addition et de la soustraction devraient maintenant être assimilés, ainsi que l'utilisation du flag de retenue.

★ ANNÉES: 1985
★ AUTEUR: T. Hebertson
★ CONVERTION: CRACKERS VELUS

Page précédente : Dr.Watson - Autoformation à l'assembleur par Micro Application - Chapitre 03
 
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.7-desktop/c
Page créée en 015 millisecondes et consultée 1384 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.