Multiplication / Division

Multiplication par décalages/additions

ASLA: arithmetic shift left (décalage vers la gauche)

En base décimal, chaque fois que l'on décale un nombre vers la gauche, on le multiplie par 10.

Ainsi, si je décale vers la gauche le nombre 5, il devient 50. Si je le décale une seconde fois, il devient 500.

En binaire, chaque décalage vers la gauche, multiplie le nombre par 2.

Si je décale 510 : 0000 0000 0000 0101 vers la gauche il devient
            1010 : 0000 0000 0000 1010 vers la gauche il devient
            2010 : 0000 0000 0001 0100

Le bit de gauche qui est perdu lors du décalage se retrouve dans le témoin de retenue(Carry).

Je désire multiplier un nombre par 10 mais l'instruction MULT n'existe pas.

Je peux:

1) additionner 10 fois le nombre (pas fort!)

2) a) décaler le nombre vers la gauche (*2)
   b) décaler le nombre vers la gauche (*4)
   c) additionner le nombre original   (*5)
   d) décaler le nombre vers la gauche (*10)

Il s'agit de trouver la bonne combinaison.

exemple: multiplier par 19:

   a) décaler le nombre vers la gauche (*2)
   b) décaler le nombre vers la gauche (*4)
   c) additionner le nombre original   (*5)
   d) décaler le nombre vers la gauche (*10)
   e) décaler le nombre vers la gauche (*20)
   f) soustraire le nombre original    (*19)

L'algorithme suivant effectue la multiplication du multiplicande par le multiplicateur
pour donner le produit:

LDX       mulcateu,d       ; Faire "multiplicateur" tours de boucle
BREQ      zéro             ; on n'a pas à multiplier si le nombre est 0
LDA       0,i              ; Initialiser l'accumulateur
addition: ADDA mulcande,d
SUBX      1,i
BRNE      addition         ; Faire un autre tour si non nul
zéro:     STA produit,d

mulcande: .block 2         ; multiplicande
mulcateu: .block 2         ; multiplicateur
produit:  .block 2         ; produit
 

remarque: afin d'optimiser l'exécution, on multiplie le plus grand nombre par le plus petit.
ex: 5*1000 -> 1000*5

 

Division par décalages/soustractions

ASRA: arithmetic shift right (décalage vers la droite)

En base décimal, chaque fois que l'on décale un nombre vers la droite, on le divise par 10.

Ainsi, si je décale vers la droite le nombre 500, il devient 50. Si je le décale une seconde fois, il devient 5.

En binaire, chaque décalage vers la droite, divise le nombre par 2.

Ainsi,

Si je décale1510 : 0000 0000 0000 1111 vers la droite il devient
             710  : 0000 0000 0000 0111 vers la droite il devient
             310 : 0000 0000 0000 0011

Le bit de droite perdu lors du décalage se retrouve dans le témoin de retenue(Carry).
 

Je désire diviser un DIVIDENDE par DIVISEUR mais l'instruction DIV n'existe pas.

Si le diviseur est un multiple de 2, je peux décaler vers la droite.
ex: diviser un nombre par 8 demandera 3 décalages vers la droite.

Si le diviseur n'est pas un multiple de 2 alors:

Je dois soustraire le diviseur du dividende tant que c'est possible.

ex: 14 / 3

DIVIDENDE COMPTEUR
    14    0
    11    1
     8    2
     5    3
     2    4
    -1    5  ; UNE FOIS DE TROP
     2    4  ; ON DÉFAIT LA DERNIÈRE SOUSTRACTION

réponse: 4 reste 2

L'algorithme suivant effectue la division du dividende par le diviseur
pour donner le quotient et le reste:

LDA       dividend,d ; dividende

LDX       0,i        ; futur quotient

soustrai: ADDX 1,i

SUBA      diviseur,d

BRGE      soustrai

;                      à ce stade, nous avons soustrait une fois de trop

SUBX      1,i        ; défaisons la dernière soustraction

ADDA      diviseur,d

STX       quotient,d

STA       reste,d

dividend:  .block 2   ; #2d
diviseur:  .block 2   ; #2d
quotient:  .block 2   ; #2d
reste:     .block 2   ; #2d