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

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

CHAPITRE 6

MULTIPLICATION, DIVISION ET GROUPE ROTATION

Presque toutes les applications réelles des ordinateurs demandent la manipulation des nombres. Alors que quelques unes ne demandent qu'une addition ou une soustraction fondamentale/ d'autres demandent la multiplication et la division. Dans ce chapitre nous verrons comment ces fonctions arithmétiques peuvent être réalisées en langage assembleur.

MULTIPLICATION BINAIRE

Avant de nous embarquer dans la Multiplication Binaire, observons le processus de la multiplication décimale. Prenez le total 13x14. Nous définissons 13 comme le MULTIPLICANDE et 14 comme le MULTIPLICATEUR et posons la multiplication comme ceci :

13 Multiplicande

14 Multiplicateur

--

52

130

--

182 Réponse

La multiplication est accomplie en multipliant le multiplicande par le chiffre situé à l'extrême droite du multiplicateur et en stockant ce résultat comme le "produit partiel", soit : 13x4=52. Ensuite nous multiplions le multiplicande par le chiffre suivant du multiplicateur, ce qui nous donne un deuxième produit partiel, soit : 1x13=13. On écrit ce produit partiel avec un décalage d'une position vers la gauche. Les deux produits partiels sont alors additionnés et donnent un résultat de 182, ce qui est la réponse juste. Il est tout à fait possible d'utiliser la même méthode pour effectuer une multiplication binaire.

Par exemple, pour multiplier 5x7 en binaire :

5 = 0101 (Calcul en 4 bits seulement)

7 = 0111

; 0111 = (7)

; x 0101 = (5)

; Puis en additionnant

Produit partiel 1 0111 ;0111

Produit partiel 2 00000 ;0111

Produit partiel 3 011100 ;100011

Produit partiel 1 0000000 ;100011

Rep: 100011

100011 = (1x32)+(0x16)+(0x8)+(0x4)+(1x2)+(1x1)=35

Avec 1 pour chiffre à l'extrême droite du multiplicateur, le produit partiel a la même disposition de chiffres que le multiplicande, soit : 0111, Sinon le produit partiel est zéro, soit : 0000. Tout nouveau produit partiel est écrit en le décalant d'une position vers la gauche. Ainsi la multiplication binaire se réduit à des additions successives et des décalages.

MULTIPLICATION A 8 BITS

Pour effectuer une multiplication en utilisant le Z80, nous utiliserons l'accumulateur pour garder le 'total en cours', le registre C pour garder le multiplicande et le registre E pour garder le multiplicateur. Voyons maintenant comment sont formés les produits partiels.

; 0 1 0 1

; ! ! ! !

Produit partiel 1 0111 = 0111x1 <-!-!-!-!

Produit partiel 2 0000 = 0111 x0 <-!-!-!

Produit partiel 3 0111 = 0111 x1 <-!-!

Produit partiel 4 0000 = 0111 x0 <-!

;^ ^

;^ ^

---------------------------- ;^

!0111 décalé à gauche! ; ^

!chaque fois (appelé ! -----------------

!le Produit Partiel ! !Le bit suivant !

!Invisible PPI) ! !de 0101 chaque !

---------------------- !fois. !

;-----------------

Le problème de la multiplication binaire peut être exprimé dans l'organigramme suivant.

FIGURE 6.1

Ce qu'il nous faut maintenant avant d'écrire le programme, ce sont le instructions qui nous permettront de décaler les bits dans les octets.

SRI s Logical Shift Right (Décalage Logique à Droite) de l'opérande s

Représenté en diagramme :

!---------! ;---

0---->! 7----->0! ----> !?!

!---------! ;---

Octet opérande Flag Carry (retenue)

Par exemple, examinons le décalage à droite de 10110111 avec l'instruction SRL,

;Octet ; Flag Carry

Avant 1 0 1 1 0 1 1 1 ; ?

Après 0 1 0 1 1 0 1 1 ; 1

Le bit 7 a été remplacé par un 0,les bits 1 à 6 décalés à droite d'une position et le bit 0 placé dans le flag Carry (retenue).

Maintenant le programme:

PROGRAMME 6.1

LD A,0 Accumulateur a Zéro

LD C,7 C = Multiplicande

LD E,5 E = Multiplicateur

LD B, 4 ;B = Compte (pour 4 bits)

ADD: SRL C ; Décaler C à droite

JR NC,NOADD: Si bit a l'extrême droite = 0 alors sauter à NOADD

ADD A,E Ajouter PPI au total en cours dans l'accumulateur

NOADD: SLA E ; Décaler PPI à gauche

DEC B ; Décrémenter le compteur

JR NZ,ADD: Resauter à ADD s'il y a encore des bits a multiplier

ADD A,65 ;Ajouter décalage

CALL &BB5A Afficher le caractère sur l'écran

RET ; Retour

Un décalage de 65 est utilisé donnant l'affichage sur l'écran du caractère ayant pour code ASCII 100- soit la lettre minuscule d (La réponse à 7x5 était 35, 35+65=100).

EXERCICE 6.1

Ecrivez un programme pour multiplier 10x9. Puis afficher le résultat directement sur l'écran.

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

Le programme 6.1 ne peut que multiplier deux nombres ayant pour résultat un total inférieur à 255. ta principale raison de cette limitation est que le produit partiel invisible est décalé à gauche et sera finalement décalé complètement hors du registre, Un problème similaire s'est présenté lorsque nous faisions une addition et une soustraction à 16 bits, le problème était résolu en rechargeant le registre de gauche avec le bit de retenue quand il y avait dépassement. Ce qu'il faut maintenant, c'est une instruction qui, après une instruction de décalage sur l'octet faible, décalera l'octet fort ainsi que toute retenue générée. Cela se fait avec l'instruction suivante :

RL s Rotation à gauche de l'opérande s ainsi que du bit de retenue.

En diagramme :

Bit de retenue

(Carry) Opérande

------------>-------------

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

--<-! !-----! 7 --- ------------

Le flag de retenue est chargé dans le bit 0, les bits 1-8 sont décalés à gauche d'une position et le flag Carry reçoit le bit 7.

Pour décaler un registre à 16 bits il nous faut donc deux instructions. L'octet faible est décalé normalement avec l'instruction SLA, puis l'octet fort est décalé avec RL. Par exemple, supposons que nous voulions décaler a gauche le contenu de DE. Les instructions suivantes accompliraient cela :

SLA E

RL D

Incorporons cette Instruction dans un programme.

Problème :

Affichez sur l'écran le résultat de l'opération suivante: 7x10 = ?

PROGRAMME 6.2

LD C,7 ;C = Multiplicande

LD E,10 E = Multiplicateur

LD D,0 ;Registre D a zéro

LD B,8 B = Nombre de bits

LD HL,0 HL à zéro, on l'utilise pour garder le total actuel

NXTB: SRL C Décaler Multiplicande a droite

JR NC,NOADD: Si retenue=0 sauter à NOADD

ADD HL,DE Ajouter PPI au total en cours

NOADD: SLA E ;Décaler octet faible à gauche

; RL D ;Recharger la retenue et décalez D à gauche

; DEC B Décrémenter compteur

JR NZ,NXTB: Resauter si encore des bits

LD A,L ;Charger dans A la réponse RET

NB. Bien que nous ayons utilisé un registre a 16 bits pour le résultat en sélectionnant soigneusement le multiplicateur et le multiplicande, seul l'octet faible contient une valeur, ce qui nous permet de l'afficher sur l'écran.

EXERCICE 6.2

En utilisant le programme 6.2 calculer la réponse de 146x124. Notez que cela donnera une réponse a 16 bits, donc H et L devront être affichés sur l'écran.

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

Le programme 6.2 a utilisé le registre B comme compteur, Chaque fois que le multiplicateur était décalé à gauche, B était décrémenté puis testé. Cette opération demande deux instructions: DEC et JR NZ. Ces deux instructions, peuvent néanmoins être remplacées par une seule, qui rend le programme plus efficace et plus élégant.

DJNZ e Décrémenter B et si cela donne une réponse Non-Zéro sauter a l'adresse mémoire e.

EXERCICE 6.3

Remplacez les Instructions DEC B et JR NZ-NXTB par une instruction DJNZ NXTB dans le programme 6.2, ou dans votre réponse a l'exercice 6.2

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

La division binaire est aussi possible avec une méthode très similaire à celle utilisée pour la multiplication.

DIVISION BINAIRE

Observons la division suivante :

----

10 !785

D'abord nous essayons de diviser 7 par 10; comme 10 ne rentre pas dans 7 la prochaine étape c'est de prendre le 8 et d'essayer de diviser 78 par 10. Il y va sept fois et il reste 8.

7

----

10 !785

comme 10 'ne rentre pas dans'8, la prochaine étape c'est de prendre 5 et d'essayer de diviser 85 par 10. Il y va 8 fois et il reste 5.

78

---- reste 5

10 !785

Donc le résultat est 78 et le reste 5. Cette forme de division est appelée "division entière" puisque les fractions en sont exclues.

Comme pour la multiplication les différents nombres d'une division ont des noms; par exemple "reste" est déjà familier. Les autres noms sont :

; quotient

; !

; 78--------!

; ----

10 !785 reste = 5

^ ^

;^-------- Dividende

Diviseur--

Etudions maintenant une division de 16 bits par 8 bits.

Problème Afficher sur l'écran le résultat de la division suivante dans un format reconnaissable.

2765 : 75 = ?

La division binaire se fait de la manière suivante, Si sans emprunt (retenue négative), le diviseur à 8 bits peut être soustrait de l'octet fort du dividende a 16 bits, alors le bit approprié de la réponse à 8 bits est mis. Ce procédé se répète huit fois, donnant un quotient à 8 bits et un reste à 8 bits.

PROGRAMME 6.3

LD HL,2765 HL = Dividende

LD C,75 ;C = Diviseur

LD B,8 ; B = compte

NXT: ADD HL,HL ;Décaler dividende a gauche

LD A,H ; A = octet fort du dividende

SUB C ; Soustraire diviseur

JR C,NXTB: Si retenue sauter à NXT

LD H,A ; Recharger octet fort du dividende

INC L ; Incrémenter la réponse

NXTB: DEC B ; Décrémenter le compteur

JR NZ,NXT: Si non-zéro sauter à NXT

LD A,L ; A = réponse (quotient)

CALL &BB5A Afficher la réponse

LD A, H ;A = reste

CALL &BB5A Afficher le reste RET

Lancez le programme. Il affichera '$A' sur l'écran, ici le code ASCII de !$! correspond à la réponse et 'A' au reste. Vérifiez que ceux-ci soient justes. Il faut noter que comme le Z80 ne possède pas une instruction

de décalage à gauche à 16 bits, on a utilisé ADD HL,HL. En binaire, ajouter un nombre à lui-même c'est la même chose que de le décaler à gauche d'une position bit, ou de le multiplier par deux. Si vous comparez cela avec la base 10, par exemple, décaler 19 à gauche, cela donnera 190 -l'équivalent d'une multiplication par 10. A votre avis, qu'est-ce qui se passerait si on décalait d'une position bit a droite un nombre binaire ? (Réponse : c'est la même chose que de diviser par 2).

Jusqu'ici, seules quelques instructions de décalage du Z80 on été utilisées pur des routines de multiplication et division d'usage général. Il est quelque fois Plus facile et plus rapide d'utiliser un petit groupe d'instructions de décalage ou de rotation pour exécuter une opération arithmétique spécifique.

Quand on utilise une instruction de rotation par opposition à une instruction de décalage, le contenu du registre est modifié, mais aucune information n'est perdue, c'est à dire qu'aucun bit ne disparaîtra sans laisser de trace. Voici une instruction qui fait Pivoter à gauche le contenu de l'accumulateur :

RLCA Rotation à gauche de l'Accumulateur et chargement d'une copie du bit 7

dans le flag Carry.

RLCA sous forme de diagramme :

Flag Carry Accumulateur

; -------->-------

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

! !-----------!7<---0!<----

---- ;--------

Notez que le bit 7 n'est cas perdu mais inséré dans le bit 0. Une Instruction pour faire pivoter à droite le contenu de l'accumulateur existe également :

RRCA Rotation à droite (Right) du contenu de l'Accumulateur et chargement

;d'une copie du bit 0 dans le flag de retenue.

Utilisons ces deux Instructions.

Problème : Multipliez 10 par 16, affichez sur l'écran le résultat, divisez ce résultat par 2 et

; affichez le sur l'écran.

PROGRAMME 6.5

LD A,10 A=10

RLCA A=20

RLCA A=40

RLCA A=80

RLCA A=160

CALL &BB5A Affiche A ('•')

RRCA A=80

CALL &BB5A Affiche A('P')

RET

EXERCICE 6.4

Ecrivez un programme pour calculer et afficher sur l'écran les résultats des opérations suivantes en utilisant des instructions de rotation et d'addition.

1. 5 x 32 = (160)

2. 254 – 2 = (127)

Les réponses possibles sont données dans le chapitre solutions.

Le Z80 possède encore d'autres Instructions de rotation et de décalage que nous n'avons pas utilisées. Elles sont détaillées dans les appendices sous le titre 'Jeu d'instructions du Z80',

Observons maintenant un jeu d'instructions oui permet la mise, l'annulation et le test de bits isolés au sein d'un octet.

LE GROUPE MISE, ANNULATION ET TEST DE BIT

Examinez l'instruction suivante :

BIT b,r Teste le bit à la position b dans l'opérande r.

Cette instruction est utilisée chaque fois qu'un bit particulier dans un octet a besoin d'être testé, par exemple dans les opérations d'entrée/sortie.

Pour illustrer l'utilisation de cette commande, un registre sera mis à zéro, incrémenté jusqu'à la mise du bit 7, le contenu du registre qui en résultera sera alors affiché sur l'écran.

PROGRAMME 6.6

LD A,0 ; A=0

NXT: INC A ; Incrémenter A

BIT 7,A ; Tester bit 7 de l'accumulateur

JR Z,NXT: ; Le bit 7 est-il mis ?

CALL &BB5A ; Afficher contenu de A sur écran

RET

Ce programme charge zéro dans A et l'incrémente continuellement jusqu'à la mise du bit 7. Lancez-le; on ne remarque pas grand chose puisque la mise du bit 7 correspond à 128 en décimal, un espace en ASCII. Essayez d'insérer soit

l'instruction INC A soit l'instruction DEC A juste avant l'instruction CALL &BB5A, pour imprimer quelque chose de visible sur l'écran.

Deux autres instructions de bit existent: l'une pour mettre le bit et l'autre pour annuler un bit individuel dans un octet.

SET b,r Met le bit en position b dans l'opérande r.

RES b,r Annule (RESet) le bit en position b dans l'opérande r.

Pour illustrer ces instructions, observons le code ASCII de 'C', en binaire 01000011. Si le bit 0 est annulé, c'est la même chose que soustraire un, ce qui donne la représentation ASCII de B.

PROGRAMME 6.7

LD A, 67 A=ASCII pour 'C'

CALL &BB5A Affiche 'C'

RES 0,A ;Annule bit 0

CALL &BB5A Affiche 'B'

SET 0,A ;Met le bit 0

CALL &BB5A Affiche 'C'

RET

EXERCICE 6.5

Ecrivez un programme qui charge 255 dans l'accumulateur, affiche le contenu sur l'écran, annule le bit 4, affiche le résultat sur l'écran, met le bit 1, annule le bit 3 et puis affiche le résultat final sur l'écran.

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

Voilà un autre chapitre terminé, à présent vous devriez avoir une assez bonne idée de comment écrire un programme relativement complexe.

Et pour résumé:

RESUME

Les notions et les groupes d'instructions suivants devraient à présent vous être assez familiers :

1. Multiplication et division binaires

2. Le groupe décalage et rotation

3. La groupe mise, annulation et test de bit.

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

Page précédente : Dr.Watson - Autoformation à l'assembleur par Micro Application - Chapitre 05
 
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 475 millisecondes et consultée 2291 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.