Unité A5: Instructions arithmétiques
Objectifs :
À la fin de cette unité, vous saurez comment sont implantées les
quatre opérations arithmétiques : addition, soustraction, multipli-
cation et division. Vous saurez comment effectuer ces opérations sur
les opérandes dont la taille dépasse celle des registres du proces-
seur. Pour y parvenir, vous devrez maîtriser les objectifs suivants :
- décrire les instructions add, sub, mul, div ainsi que sal, sar, shl
et shr.
- expliquer le fonctionnement des programmes de précision
multiple.
On rappelle que tout le code présenté ici ou dans le supplément est
disponible sous forme de projet exécutable dans le fichier Code.zip
disponible sur le site du cours.
©Pierre Marchand, 2001 168
Unité A5: Instructions arithmétiques
8.1 Addition
L'instruction add fait l'addition des deux opérandes et enregistre le
résultat dans l'opérande destination. Les indicateurs sont positionnés
selon le résultat de l'opération. Elle ne tient pas compte d’une retenue
antérieure, mais affecte le bit CF si elle génère une retenue.
L'instruction addc fait l'addition de deux opérandes plus le bit de
retenue CF provenant d'une opération antér i e u r e . E l l e s e r t à
additionner les octets/mots/doubles mots de poids fort à la suite de
l'addition des octets/mots/doubles mots de poids plus faible dans une
addition portant sur plusieurs octets/mots/doubles mots comme dans
l'addition de précision qui suit.
©Pierre Marchand, 2001 169
1
Unité A5: Instructions arithmétiques
8.1 Addition
Addition de précision
C C C
+ + +
A3 A2 A1 A0
+ + + +
B3 B2 B1 B0
S3 S2 S2 S0
Poids fort Poids faible
Adresse haute Adresse basse
©Pierre Marchand, 2001 170
Unité A5: Instructions arithmétiques
8.1 Addition
Addition de précision
Voici comment on pourrait coder une telle opération :
lea esi, A ; charger adresse des opérandes
lea edi, B
lea ebx, S
clc ; retenue initiale = 0
mov ecx, n ; nombre de mots
lp: mov eax, [esi]
adc eax, [edi]
mov [ebx], eax
add esi, 4 ; + 4 à chaque pointeur car 32 bits = 4 o.
add edi, 4
add ebx, 4
loop lp ; ou dec ecx et jne lp
©Pierre Marchand, 2001 171
2
Unité A5: Instructions arithmétiques
8.2 Soustraction
L'instruction sub effectue la soustraction de l'opérande source de
l'opérande destination et place le résultat dans l'opérande destination. Si
un emprunt est nécessaire, le bit CF est mis à 1.
L'instruction subc tient compte de cet emprunt dans une soustraction de
précision.
©Pierre Marchand, 2001 172
Unité A5: Instructions arithmétiques
8.3 Multiplication
Il y a deux instructions pour la multiplication: mul, qui considère les
opérandes comme des quantités non signées (toujours positives) et
imul, qui considère les opérandes comme des quantités signées en
complément à 2. Ces instructions considèrent qu'il y a un opérande
destination implicite qui est la paire de registres edx:eax pour les
opérations sur 32 bits, dx:ax pour les opérations sur 16 bits et ax pour les
opérations sur 8 bits.
©Pierre Marchand, 2001 173
3
Unité A5: Instructions arithmétiques
8.3 Multiplication
La syntaxe est la suivante :
mul reg ; multiplie eax par reg -> edx:eax
mul mem
imul reg
imul mem
imul reg, immed ; multiplie reg par immed -> reg
imul reg1, reg2, immed ; multiplie reg2 par immed -> reg1
imul reg1, reg2 ; multiplie reg1 par reg2 -> reg1
©Pierre Marchand, 2001 174
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication non signée
Supposons que eax = 0x80000001. eax peut être interprété comme:
2 147 483 649 (non signé)
ou -2 147 483 647 (signé)
Si ebx = 0x00000003, alors:
mul ebx → eax = 0x80000003
edx = 0x00000001
La réponse est le nombre 0x00000001 8000003,
qui vaut 6 442 450 94710.
©Pierre Marchand, 2001 175
4
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication non signée
CF et OF sont mis à 1 si AH n’est pas 0 pour des opérandes de 8
bits ou si DX n’est pas 0 pour des opérandes de 16 bits ou si EDX
n’est pas 0 pour des opérandes de 32 bits.
©Pierre Marchand, 2001 176
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication signée
Par contre, avec les mêmes opérandes,
imul ebx → eax = 0x80000003
edx= 0xFFFFFFFE
et la réponse est le nombre $FFFFFFE 80000003,
qui vaut -6 442 450 94110.
Remarquez que dans les deux cas, le double mot de poids faible est
le même.
CF et OF sont mis à 1 si le produit est étendu en signe dans AH
pour des opérandes de 8 bits ou dans DX pour des opérandes de 16
bits ou dans EDX pour des opérandes de 32 bits.
©Pierre Marchand, 2001 177
5
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication signée
Avec la forme à deux opérandes,
imul reg, immed
imul reg, reg
imul reg, mem
Le registre de gauche, de 16 ou 32 bits, contient l’un des facteurs et
sert de destination pour le résultat. L’autre facteur est soit le registre
de droite, soit une donnée immédiate, soit un opérande mémoire.
Les deux opérandes doivent être de même taille.
OF et CF sont mis à 1 si le résultat est trop grand pour entrer dans le
registre destination.
©Pierre Marchand, 2001 178
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication signée
Avec la forme à trois opérandes, le premier est un registre de 16 ou
32 bits dans lequel le résultat sera enregistré. Le deuxième est un
registre de même taille ou un opérande mémoire contenant le
premier facteur, le troisième est une valeur immédiate représentant
l’autre facteur.
OF et CF sont mis à 1 si le résultat est trop grand pour entrer dans le
registre destination.
©Pierre Marchand, 2001 179
6
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication signée
Exemples:
imul ebx // edx:eax = eax * ebx
imul eax, ebx // eax = eax * ebx
imul ax, word ptr [esi] // ax = ax * [esi]
imul ax, 300 // ax = ax * 300
imul bx, cx, 3 // bx = cx * 3
imul ebx, dword ptr [esi], 3 // ebx = [esi] * 3
©Pierre Marchand, 2001 180
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication signée
Les formes à 2 et 3 opérandes peuvent être utilisées aussi bien pour
la multiplication signée ou non signée. En effet, elles ne gardent que
la moitié de poids faible du produit. Or cette moitié est la même, que
le produit soit signé ou non signé.
©Pierre Marchand, 2001 181
7
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication de précision
Supposons qu'on multiplie en décimal deux nombres de deux
chiffres chacun, par exemple 45 × 67. On peut effectuer le calcul au
moyen de quatre multiplications d'un chiffre par l'autre comme suit :
45
× 67
1 35
28
30
24
3015
On obtient un produit de quatre chiffres.
©Pierre Marchand, 2001 182
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication de précision
De la même façon, multiplions deux nombres de 64 bits constitués
chacun de deux doubles mots de 32 bits. L'instruction mul peut
effectuer le produit 32 bits par 32 bits et donner le résultat de 64 bits
dans edx:eax. On effectue quatre produits comme dans le cas
décimal ci-dessus, on effectue l'addition de quatre nombres décalés,
et on obtient le résultat de 128 bits.
©Pierre Marchand, 2001 183
8
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication de précision
XH XL
*
YH YL
XL * YL
+ XH * YL
+ XL * YH
+ XH * YH
= Produit de 128 bits
La principale difficulté consiste à effectuer l'addition sur 128 bits des
nombres décalés en faisant attention de bien propager les retenues
s'il y en a.
©Pierre Marchand, 2001 184
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication de précision
X dd 0FFFFFFFFh, 0FFFFFFFFh
Y dd 0FFFFFFFFh, 0FFFFFFFFh
Produit dd 4 dup(?)
lea esi, X ; chargement de l'adresse des opérandes
lea edi, Y
lea ebx, Produit
©Pierre Marchand, 2001 185
9
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication de précision
mov eax, [esi] ; XL
mul [edi] ; YL
mov [ebx], eax ; (XL x YL)L
mov [ebx + 4], edx ; (XL x YL)H
mov eax, [esi + 4] ; XH
mul [edi] ; YL
add [ebx+4], eax ; (XH x YL)L
mov [ebx + 8], edx ; (XH x YL)H
adc [ebx + 8], 0 ; propager retenue
mov [ebx+12], 0
adc dword ptr [ebx +12], 0
mov eax, [esi] ; XL
mul [edi + 4] ; YH
©Pierre Marchand, 2001 186
Unité A5: Instructions arithmétiques
8.3 Multiplication
Multiplication de précision
add [ebx + 4], eax ; (XL x YH)L
adc [ebx + 8], edx ; (XL x YH)H
adc dword ptr [ebx + 12], 0 ; propager retenue
mov eax, [esi + 4] ; XH
mul [edi + 4] ; YH
add [ecx + 8], eax ; (XH x YH)L
mov [ebx + 12], edx ; (XH x YH)H
adc dword ptr [ebx + 12], 0 ; propager retenue
Le résultat en mémoire est :
Produit = 0x01000000, 0x00000000, 0xFEFFFFFF, 0xFFFFFFFF
©Pierre Marchand, 2001 187
10
Unité A5: Instructions arithmétiques
8.4 Division
Comme pour la multiplication, il y a deux instructions pour la division,
div pour la division non signée, et idiv pour la division signée. Comme
pour la multiplication, il y a un opérande destination implicite qui est la
paire de registres edx:eax pour les opérations sur 32 bits, dx:ax pour les
opérations sur 16 bits et ax pour les opérations sur 8 bits.
La syntaxe est la suivante :
div reg
div mem
idiv reg
idiv mem
Les indicateurs CF et OF ne sont pas affectés lors de la division.
©Pierre Marchand, 2001 188
Unité A5: Instructions arithmétiques
8.4 Division
Exemples
mov eax, 5282 ; eax = 0x000014A2
cdq ; edx = 0 -> edx:eax = 5282 sur 64 bits
mov ebx, 10
idiv ebx -> edx = reste = 0x00000002 = 210
eax = 0x00000210 = 52810
mov eax, -5282 ; eax = -5282 = 0xFFFFEB5E
cdq ; edx = 0xFFFFFFFF
; edx:eax = -5282 sur 64 bits
mov ebx, 10
idiv ebx -> edx = reste = 0xFFFFFFFE = -2,
eax = quotient = 0xFFFFFDF0 = -52810
©Pierre Marchand, 2001 189
11
Unité A5: Instructions arithmétiques
8.4 Division
Exemple de division 16 bits
short dix = 10;
mov eax, 5282 ; ax = 0x0000 14A2
div word ptr dix ; eax = 0x0002 0210
; reste = 2, ax = quotient = 52810
mov eax, -5282 ; eax = 0xFFFF EB5E = -528210 sur 32 bits
idiv word ptr dix ; eax = 0xFFFE FDF0
; reste = FFFE = -2
; ax = FDF0 = -52810
©Pierre Marchand, 2001 190
Unité A5: Instructions arithmétiques
8.4 Division
Division signée
Supposons que eax = 0xFFFFFFF8
eax peut être interprété comme:
4 294 967 28810 (non signé)
ou -810 (signé)
Si ebx = 0x00000003 et edx = 0x00000000, alors :
div ebx → eax = 0x55555552
edx = 0x00000002
qui vaut 1 431 655 76210, reste 2.
©Pierre Marchand, 2001 191
12
Unité A5: Instructions arithmétiques
8.4 Division
Division signée
Mais si ebx = 0x00000003 et edx = 0xFFFFFFFF
idiv ebx → eax = 0xFFFFFFFE,
edx = 0xFFFFFFFE
qui vaut -210, reste -2.
Si ebx = 0x00000003 et edx = 0xFFFFFFFF
div ebx → débordement de capacité
parce que le quotient est > 32 bits.
©Pierre Marchand, 2001 192
Unité A5: Instructions arithmétiques
8.5 Décalages
L'architecture Intel supporte plusieurs instructions de décalage. On
peut distinguer entre les décalages arithmétiques, sal, décalage
arithmétique vers la gauche, et sar, décalage arithmétique vers la
droite, et les décalages logiques, shl, décalage logique vers la
gauche et shr, décalage logique vers la droite.
Pour des décalages multiples, le nombre de bits à d écaler est
placé dans le registre de 8 bits CL ou dans un opérande immédiat
de 8 bits.
Il existe deux autres instruction de décalage, shld et shrd pour
passer les bits d'un registre à un autre.
©Pierre Marchand, 2001 193
13
Unité A5: Instructions arithmétiques
8.5 Décalages
Décalage à gauche
Le décalage arithmétique vers la gauche et le décalage logique
vers la gauche sont identiques. Tous les bits sont déplacés de n
bits vers la gauche, et les positions laissées libres à droite sont
remplacées par des 0. Le dernier bit sortant à gauche est placé
dans l'indicateur de retenue CF.
CF 0
Syntaxe :
shl reg, 1 sal reg, 1
shl mem, 1 sal mem, 1
shl reg, cl sal reg, cl
shl mem, cl sal mem, cl
shl reg, immed8 sal reg, immed8
shl mem, immed8 sal mem, immed8
©Pierre Marchand, 2001 194
Unité A5: Instructions arithmétiques
8.5 Décalages
Décalage logique à droite
Le décalage logique vers la droite déplace tous les bits de n bits
vers la droite, et les positions laissées libres à gauche sont
remplacées par des 0. Le dernier bit sortant à droite est placé dans
l'indicateur de retenue CF.
0 CF
Syntaxe :
shr reg, 1
shr mem, 1
shr reg, cl
shr mem, cl
shr reg, immed8
shr mem, immed8
©Pierre Marchand, 2001 195
14
Unité A5: Instructions arithmétiques
8.5 Décalages
Décalage arithmétique à droite
Le décalage arithmétique vers la droite déplace tous les bits de n
bits vers la droite, et les positions laissées libres à gauche sont
remplacées par le bit de signe. Le dernier bit sortant à droite est
placé dans l'indicateur de retenue CF.
CF
Syntaxe :
sar reg, 1
sar mem, 1
sar reg, cl
sar mem, cl
sar reg, immed8
sar mem, immed8
©Pierre Marchand, 2001 196
Unité A5: Instructions arithmétiques
8.5 Décalages
Décalages de double précision
Les deux dernières instructions de décalage, shld e t shrd,
décalent les bits du deuxième opérande dans le premier opérande.
Le nombre de bits à décaler est spécifié par le troisième opérande.
shld d écale le premier opérande de n bits vers la gauche. Les
positions laissées vacantes sont remplies par les n bits les plus
significatifs du deuxième opérande.
shrd d écale le premier opérande de n bits vers la droite. Les
positions laissées vacantes sont remplies par les n bits les moins
significatifs du deuxième opérande.
©Pierre Marchand, 2001 197
15
Unité A5: Instructions arithmétiques
8.5 Décalages
Décalages de double précision
Syntaxe :
shld/shrd reg, reg, immed
shld/shrd reg, reg, CL
shld/shrd mem, reg, immed
shld/shrd mem, reg, CL
©Pierre Marchand, 2001 198
Unité A5: Instructions arithmétiques
8.5 Décalages
Division au moyen de décalages
Considérons d ’abord la division binaire suivante :
1 0 0 1 1 1 / 1 1 1
-1 1 1 0
-1 1 1 1
0 0 1 0 1 1
-1 1 1 0
-1 1 1 1
0 0 0 1 0 0
Donc, 39/7 = 5, reste 4.
Cette méthode peut être appliquée telle quelle, sauf qu'il faut trouver
une façon commode pour l'ordinateur de comparer au diviseur les bits
les plus significatifs du dividende.
©Pierre Marchand, 2001 199
16
Unité A5: Instructions arithmétiques
8.5 Décalages
Division au moyen de décalages
On effectue cette opération au moyen de décalages d'un registre Q
contenant le dividende D à un autre registre R qui contiendra
éventuellement le reste.
R Q
1 si R ≥ D
Initialement, R = 0 et Q = dividende. On décale Q vers R bit par bit.
À chaque décalage, si R ≥ D, on remplace R par R - D et on insère
un 1 à droite du quotient, sinon on insère un 0. Comme à chaque
décalage une position est libérée à droite de Q, on peut économiser
un registre en utilisant ces positions pour insérer les bits du
quotient. On répète cette opération tant qu'il y a de bits dans le
registre Q, par exemple 16 ou 32 fois. Finalement, on décale Q une
dernière fois à gauche pour y insérer le dernier bit du quotient. À la
fin de l'opération R contient le reste et Q, le quotient.
©Pierre Marchand, 2001 200
Unité A5: Instructions arithmétiques
8.5 Décalages
Division au moyen de décalages
Division (101111 / 100) -> 1011 reste 011
R D Décalage no.
000000 101111
000001 011110 Q=0 1
000010 111100 Q=00 2
000101 111000 Q=000 3
000100
000001
000011 110000 Q=0001 4
000111 100000 Q=00010 5
000100
000011
000111 000000 Q=000101 6
000100
000011
Q=0001011 7
©Pierre Marchand, 2001 201
17
Unité A5: Instructions arithmétiques
8.5 Décalages
Division au moyen de décalages
Division 32 bits / 32 bits
mov edx,dividende // edx = Q
mov ebx,diviseur // ebx = D
mov ecx,32 // 32 décalages en tout
mov esi,0 // bit quotient = 0
xor eax,eax // eax = R = 0
decal: shld eax,edx,1 // décaler dividende dans eax
shl edx,1 // décaler dividende
add edx,esi // ajouter bit quotient à droite
mov esi,0 // bit quotient = 0
cmp eax,ebx // R > D ?
jb suivt // si oui, soustraire diviseur, sinon suivant
©Pierre Marchand, 2001 202
Unité A5: Instructions arithmétiques
8.5 Décalages
Division au moyen de décalages
sub eax,ebx ; soustraire diviseur
mov esi,1 ; bit quotient = 1
suivt: loop decal ; ou dec ecx, jne decal
shl edx,1 ; dernier décalage quotient
add edx,esi ; dernier bit du quotient
; quotient dans edx
; reste dans eax
Voir animation à la page
http://wwwbacc.ift.ulaval.ca/~ift17583/Arithm.html
©Pierre Marchand, 2001 203
18
Unité A5: Instructions arithmétiques
8.5 Décalages
Division de précision au moyen de décalages
Supposons qu'on veuille effectuer la division d'un nombre de 128 bits
par un nombre de 64 bits. L'opération se fera plutôt sur des opérandes
mémoire que dans des registres. Chaque rectangle dans l'illustration
suivante représente un double mot de 32 bits. On utilise le même
algorithme que précédemment :
R Q
R+4 R Q+12 Q+8 Q+4 Q 1 si R ≥ D
D
D+4 D
La légende sous chaque rectangle représente son adresse.
©Pierre Marchand, 2001 204
Unité A5: Instructions arithmétiques
8.5 Décalages
Division de précision au moyen de décalages
Pour effectuer cette opération, on a besoin des fonctionnalités
suivantes (fonctions ou macros) :
longShiftLeft(src, dwords, shifts)
longCompare(dst, src, dwords)
longSub(dst, src, dwords)
Voici comment on pourrait l'implanter en pseudo code. Les trois
fonctions ci-dessus vous sont laissées comme exercice.
On suppose que Q contient le dividende de 128 bits (4 doubles
mots) et que R est 0 sur 64 bits. L'algorithme est exactement le
même que pour la division binaire au moyen de décalages
présentée plus haut.
©Pierre Marchand, 2001 205
19
Unité A5: Instructions arithmétiques
8.5 Décalages
Division de précision au moyen de décalages
q=0
decal: longShiftLeft(R, 2, 1) ; décalage de R de 1 vers la gauche
shld R, Q+12, 1 ; passage du bit le plus significatif de Q
longShiftLeft(Q, 4, 1) ; décalage de Q de 1 vers la gauche
add Q, q ; bit de quotient dans le bit le moins
q=0 ; significatif de Q
longCompare(R, D, 2) ; R > D?
jl suivt
longSub(R, D, 2) ; si oui, R = R - D
q=1
suivt: loop decal
longShiftLeft(Q, r, 1) ; dernier décalage de Q
add Q, q ; dernier bit de quotient
©Pierre Marchand, 2001 206
Unité A5: Instructions arithmétiques
8.6 Rotations
Il y a deux types de rotations dans l’architecture Intel IA-32. La rotation
simple rol et ror et la rotation avec le bit de retenue, rocl et rocr.
ROL
CF
ROCL
CF
ROR
CF
ROCR
CF
©Pierre Marchand, 2001 207
20
Unité A5: Instructions arithmétiques
8.6 Rotations
OF n’est affecté que par les rotations sur 1 bit. La valeur est donnée
par MSB(dest) ⊕ CF , où MSB = bit le plus significatif.
Syntaxe :
rol/ror/rocl/rocr reg, 1
rol/ror/rocl/rocr mem, 1
rol/ror/rocl/rocr reg, cl
rol/ror/rocl/rocr mem, cl
rol/ror/rocl/rocr reg, immed8
rol/ror/rocl/rocr mem, immed8
©Pierre Marchand, 2001 208
Unité A5: Instructions arithmétiques
8.6 Rotations
Exemples
mov eax, 0x8FFFFFFF
rol eax, 1 ; EAX = 0x1FFFFFFF; CF = 1; OF = 1;
clc
mov eax, 0x8FFFFFFF
rcl eax, 1 ; EAX = 0x1FFFFFFE; CF = 1; OF = 1;
©Pierre Marchand, 2001 209
21