CODING ★ LES ROTATIONS et DIVISIONS ★

Assembleur ACPC n°28 - Les rotations & divisions

Je trouve qu'on s'est bien amusés les mois précédents et qu'il serait sage et judicieux de passer à des choses moins drôles mais tout aussi passionnantes. J'avais vendu la mèche le mois dernier, nous allons voir ensemble quelques routines mathématiques indispensables dans les programmes assembleur.

Pour ceux qui se posaient plein de questions concernant les rotations et décalages d'octets, un rayon de soleil va illuminer les coins sombres de leur savoir. Avant d'entrer dans de longues explications et pour une meilleure compréhension, je vous donne les différents types de rotations et décalages qui sont applicables à tous les registres 8 bits "A, B, C, D, E, H, L", ainsi qu'aux contenus des registres HL, IX et IY "(HL), (IX+n), (IY+n)".

LES ROTATIONS

RL, RLC, RR, RRC, et RLA, RLCA, RRA, RRCA

Les quatre premières rotations sont valables pour tous les registres, comme dit plus haut. Par contre, les quatre suivantes sont des exclusivités du père accumulateur.

  • RL décale les bits du registre vers la gauche et passe la carry dans le bit 0, alors que le bit 7 va, quant à lui, dans la çarry.
  • RLC, c'est comme RL, à la différence que le bit 0 est honoré par la valeur contenue dans le bit 7.
  • RR, décale à droite, le bit 0 va dans la carry et la carry dans le bit 7.

RRC, comme RR, si ce n'est que le bit 7 est rempli par le contenu du bit O.
Les quatre rotations RLA, RLCA RRA, RRCA sont les mêmes que celles précédemment vues, sauf qu'elles ne tiennent que sur un octet au lieu de deux, et ne concernent que l'accu. Il existe deux autres rotations que, pour l'instant, on laisse de côté, à savoir RLCA et RRCA

LES DECALAGES

C'est encore plus simple que tout à l'heure. Il n'yen a que trois: SLA, SRA et SRL.

  • SLA, décale les bits à gauche et met 0 dans le bit 0.
  • SRA, décale les bits à droite et met le bit 0 dans la carry (attention, le bit 7 ne change pas de valeur).
  • SRL, décale les bits à droite, met dans la carry le bit 0 et met 0 dans le bit 7.

Tout cela n'est pour l'instant que du chinois et vous ne pigez pas un mot de ce que je viens d'expliquer? C'est normal, car pour tout comprendre, il faut lire la suite, alors lisez, que diable!
00000001 en binaire représente 1. 00000010 dans le même langage représente 2. La différence? On a glissé les bits vers la gauche et mis. un 0 dans le bit 0. Si on refait la même opération. on trouve 00000100 qui représente 4.
Alors, on commence à se comprendre. La mnémonique SLA fait exactement la même chose, à savoir une multiplication par 2. Le résultat, toutefois, n'est représenté que sur 8 bits, donc en dessous de 255. Reportez-vous au premier petit programme et vous verrez que les deux instructions ADD M et SLA A sont similaires, elles multiplient par 2 et par 2 (donc par 4) l'accumulateur.

On doit, bien sûr, corser les choses si la valeur par laquelle doit être multiplié l'accumulateur n'est pas une puissance de 2. Pour cela, on ruse. On note les puissances de 2 et on regarde si par chance, la somme de 2 ou de 3 de ces puissances ne ferait pas l'affaire. C'est le deuxième programme qui fait une multiplication par 10. Eh oui, 8 et 2 font bien 10. On multiplie l'accu par 2 et on le place dans le registre B, on continue par 4 et par 8 et on additionne B pour obtenir le résultat demandé. Il ne vous est bien entendu pas interdit d'utiliser les soustractions ou les additions pour venir à vos fins.

PLUS SERIEUX ENCORE

Tout marche à merveille, avec deux petits inconvénients cependant. Parfois, c'est long et fastidieux et cela ne marche que pour un type de multiplication, et n'étant pas universel, cela ne peut être appelé par un CALL. De plus. le résultat est sur 8 bits et je vois votre tête pour une multiplication du genre 23*107.

Voici donc la routine universelle qui marche partout. Le troisième programme multiplie l'accumulateur avec le double registre DE et met le résultat dans HL. Bien sûr, si vous travaillez 8 bits sur 8 bits, il ne faudra pas oublier de mettre le registre D à 0. Exemple: LD A, 7 et LD E,102 et LD D,0 ou LD A,7 et LD DE,102, mais attention, dans le deuxième cas, aux débordements (le résultat doit être inférieur à &FFFF).

Voyons cela de plus près avec la valeur NB multipliée par 5. Cela revient à additionner NB*1 et NB*4. Idem pour NB*203, on pourrait faire 128*NB + 64*NB + 8*NB + 2*NB + 1 *NB. Comme vous le constatez, ces chiffres sont tous des puissances de 2. Et c'est là que les décalages et rotations vont nous venir en aide.
Pour effectuer ce type de multiplications. on regarde un par un et de droite à gauche les bits de l'accu. Si c'est l, on additionne dans HL la valeur de DE. On multiplie par 2 DE et on teste le bit suivant de l'accu, huit fois de suite. Le résultat, le voici, le voilà dans le troisieme programme.

***************************
* Doc n°1 *
* ; *
* A = A * 4 *
***************************
ADD A,A ; A = A * 2
SLA A ; A = A * 4
***************************
* Doc n°2 *
* ; *
* A = A * 10 *
***************************
SLA A ; A * 2
LD B,A ; B = A * 2
SLA A ; A * 4
SLA A ; A * 8
ADD A,B ; A * 10
***************************
* Doc n°3 *
* ; *
* HL = DE * A *
***************************
LD B,6
LD HL,0
BOUC RRA
JR NC,SAUT
ADD HL,DE
SAUT SLA E
RL D
DJNZ BOUC
***************************
* Doc n°4 *
* ; *
* A = A / 4 *
***************************
SRA A
SRA A
***************************
* Doc n°5 *
* ; *
* C = E / D *
* A = RESTE *
***************************
LD B,8
XOR A
LD C,A
BOUC SLA E
RL A
CP D
JR C,SAUT
SUB D
SAUT CCF
RL C
DJNZ BOUC

Pour tester les bits de l'accumulateur, on utilise la mnémonique RRA qui décale à droite les bits de l'accu ét place dans la carry le bit 0. De ce fait, on peut tester la carry pour savoir si l'on doit ou pas additionner à HL la valeur de DE. Dans les deux cas de figure, on multiplie par 2 le registre DE. Pour cela, un petit SLA E multiplie par 2 le registre E et place le bit 7 dans la carry. On décale le registre D de la même façon, en lui plaçant dans le bit 0 la fameuse carry qui pourrait déborder. Et voilà une multiplication. qui ne mange pas de pain, très rapide et qui peut être placée dans votre programme et appelée par un CALL. Sympa, non?

Pour votre gôuverne, et surtout pour les plus exigeants d'entre vous, dans les "Bidouilles" du mois de mai, on vous donnait une multiplication de 16 bits sur 16 avec le résultat sur 32 bits, alors si le Cœur vous en dit...

PREMIERE ET SECONDE DIVISION

Le moyen le plus simple de diviser l'accu par 2 est de décaler ces bits vers la droite. SRA A peut parfaitement faire l'affaire. Deux foix SRA A nous donne une division par 4 (quatrième programme). On peut aller ainsi jusqu'à la division par 128, car au-delà, le résultat est toujours égal à 0. Mais convenez que cela reste insuffisant. Pour y remédier, je vous propose une jolie multiplication sur 8 bits. On divise le registre E par D, on place le résultat dans C et le reste dans A Pour comprendre le pourquoi du comment de cette division, il faut, comme tout à l'heure, décortiquer le principe. Et le principe est de retrancher le diviseur par le dividende, tant que le premier est plus petit que le second.
Le CCF sert à inverser la carry (0 si égal à 1 ou 1 si égal à 0). N'oubliez pas que la mnémonique RL place dans le bit 0 de l'opérande la carry, et que le bit 7 de cette même opérande passe dans la carry.

Voilà, c'est tout pour aujourd'hui, amusez-vous bien et n'hésitez pas à m'écrire pour me demander la lune si le Cœur vous en dit.

Zède le diviseur, ACPC n°28 Juillet-Août 90, p64-65

Page précédente : Assembleur ACPC n°26

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Assembleur ACPC n°08 - Initiation : Les CALL / JR
» Coding » Assembleur ACPC n°35 - Dossier assembleur
» Coding » Bidouilles ACPC n°17 - Le catalogue AMSDOS
» Coding » Assembleur ACPC n°43
» Coding » Bidouilles ACPC n°37 - FDC en mode direct
» Coding » Assembleur ACPC n°44 - La programmation HARD du PSG
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 037 millisecondes et consultée 1675 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.