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