Vous êtes sur la page 1sur 4

Ordinateurs: structures et applications Énoncé du laboratoire 3

GIF-16116, Hiver 2006

LABORATOIRE NO 3
Addition de fractions
Ce laboratoire vaut 3% de la note totale du cours. À faire individuellement ou en équipe de 2, il sera corrigé à partir d’un fichier texte remis sur
le site web du cours (Nom du fichier = Lab2_Nom1_Prenom1_Nom2_Prenom2.asm). Le laboratoire est à remettre au plus tard vendredi le 24
février à 15h00. 20% sera retranché de la note totale du laboratoire à toutes les semaines de retard, à moins d’entente signée avec le
professeur ou la direction du programme de GEL/GIF.

OBJECTIFS:
Ce laboratoire vise les objectifs suivants:
- Maîtriser les principes de bases de la programmation en assembleur.
- Manipuler des bits et des variables sur plusieurs bytes en assembleur 8086.
- Utiliser et comprendre la plupart des instructions d’un 8086.
- Comprendre les difficultés que pose la manipulation de fractions.

Description du laboratoire :

Dans ce laboratoire, vous aurez à écrire un petit programme en assembleur. Ce programme additionnera deux
fractions sur 32 bits selon la norme IEEE754. Les contraintes pour ce programme sont décrites ci-dessous, avec
un peu de théorie pour vous aider.

Théorie :

Aspect général :

Les fractions peuvent être exprimées sur 32 bits dans le format IEEE754. Vous retrouverez la description de ces
bits dans les notes du premier cours. Pour vous aider, le programme TestFloatToHex.exe a également été mis sur
le site web du cours. Il vous permettra de visualiser et convertir des fractions représentées en binaire ou en
décimal. Par ailleurs, l’excellent site web http://ariffart.club.fr/boutils/boutils05.html vous permettra d’approfondir
sérieusement la question, au besoin.

Algorithme d’addition:

Afin d’additionner des fractions à partir de bits en mémoire, l’algorithme suivant peut être utilisé :

1) Il faut d’abord comparer les exposants des deux fractions et aligner les mantisses des deux fractions en
fonction de la différence entre les exposants. L’exposant final devrait être l’exposant le plus élevé. Par
ailleurs, un bit devrait être ajouté à la mantisse, avant l’alignement, afin de représenter le 1 ou le 0 devant
la mantisse (1 si l’exposant vaut de 1 à 255, 0 sinon).
2) Une fois les mantisses alignées, il faut effectuer l’addition (ou la soustraction) en fonction du signe des
fractions. Si les fractions sont de même signe, la somme se fait de manière non signée et le signe des
deux opérandes est transféré au résultat. Si les fractions sont de signes différents, il faut faire la
soustraction et gérer le signe du résultat. Le résultat doit toujours être remis positif.
3) Finalement, il faut calculer l’exposant et la mantisse représentant la somme de fractions. En pratique,
l’exposant de la somme devrait presque toujours être le même que le plus grand exposant des deux
opérandes. Toutefois, il faudra parfois incrémenter ou décrémenter cet exposant tout en ajustant les bits
de la mantisse. L’incrémentation se fait s’il y a une retenue lors d’addition d’opérandes de même signe.
Par construction, l’incrémentation maximale est 1. La décrémentation se fait lors d’addition d’opérandes de
signes opposés. Dans ce cas, il est possible de diminuer l’exposant de plusieurs chiffres.

Cet algorithme s’inspire des équations suivantes :

(EQ1) 2 E3 * (1 + M 3 ) = 2 E2 * (1 + M 2 ) + 2 E1 * (1 + M 1 )

Etienne Tremblay Page 1 2011-03-19


On cherche E3 et M3 sachant que ce nombre est la somme de deux fractions exprimées par un exposant et une
mantisse ( fraction1 = 2 E1 * (1 + M 1 ) et fraction2 = 2 E2 * (1 + M 2 ) ).
Il est possible d’exprimer la somme sous la forme suivante :

1+ M1
(EQ2) 2 E3 * (1 + M 3 ) = 2 E2 * (1 + M 2 + )
2 E2 − E1
L’équation EQ2 illustre la théorie. La division par 2 E2-E1 représente l’alignement des bits. Une fois les deux termes
additionnés, il reste à trouver M3 et E3. En pratique, E3 peut être déterminé par la puissance de 2 du premier 1
dans la somme de fractions. M3 est donné par les bits restants de la mantisse.

Exemples :

Exemple 1 : 6.5 + 1.25 = 7.75 (Même signe, pas d’incrémentation de l’exposant)

0 10000001 10100000000000000000000 ; 6.5


+ 0 01111111 01000000000000000000000 ; 1.25

1) La différence entre les deux exposants est 2 (129-127 = 2).

2) Les nombres sont de même signe; on met le signe du résultat à 0, et on effectue une addition sans tenir compte
des signes.

Si on ajoute 1 devant chaque mantisse pour le 1 dans la norme et que l’on aligne les mantisses après:

110100000000000000000000 ;1+M2 -> Le bit MSB vaut 1, le suivant vaut ½, celui d’après vaut ¼, etc.
+ 00101000000000000000000000 ;(1+M1)/22 –> Le bleu représente l’alignement de 2
= 111110000000000000000000

La somme est donc 111110000000000000000000.

3)

Le premier bit à 1 de la somme vaut 22 (Il s’agit de l’exposant pour 6.5). L’exposant d’une fraction représentant la
somme est donc 2+127 (129). La mantisse, elle, est constituée des bits qui suivent le premier 1 dans la somme.
En conclusion, le résultat de la somme est, selon le format IEEE754 :

0 10000001 11110000000000000000000

Ce qui est bien 7.75 !!!

Exemple 2 : 6.5 + 6.5 = 13 (Même signe, incrémentation de l’exposant)

0 10000001 10100000000000000000000 ; 6.5


+ 0 10000001 10100000000000000000000 ; 6.5

1) La différence d’exposant est 0. Il n’y a pas d’alignement à faire!


2) Ajoutons le 1 de la norme IEEE754 avant de faire l’addition :

0110100000000000000000000
+ 0110100000000000000000000
= 1101000000000000000000000

3) Le premier 1 de la somme vaut 2^3 (il y a une retenue à l’addition sur 24bits). L’exposant est donc 3+127
(130) et le reste des bits donne la mantisse :

Etienne Tremblay Page 2 2011-03-19


Réponse en format IEEE754 :

0 10000010 10100000000000000000000 ;Ce qui est bien 6.5*2 = 13!!!

Exemple 3 : 6.5 – 6.75 = -0.25 (Signes différents, décrémentation de l’exposant)

0 10000001 10100000000000000000000 ;6.5


1 10000001 10110000000000000000000 ;6.75

1) La différence des exposants est 0. Il n’y a pas d’alignement à faire.


2) Ajoutons un bit pour le 1 de la norme IEEE754 (en gras)

110100000000000000000000
- 110110000000000000000000
=
111110000000000000000000 ;Nous avons un nombre négatif comme résultat de la soustraction!

Puisque nous avons un résultat négatif, il faut mettre le signe de la somme négatif et rendre ce nombre positif :

NOT(1111100000000000000000000) + 1 =

0000011111111111111111111
+ 0000000000000000000000001
= 0000100000000000000000000 ; C’est le résultat de la somme sous forme positive

3) Le premier 1 du nombre vaut 2-2 (2^2 pour 6.5, décalé de 4 bits vers la droite). L’exposant est donc -2+127
(125) et les bits qui suivent sont nuls.

Nous avons donc comme résultat :

1 01111101 00000000000000000000000

Ce qui est bien -0.25!!!

Implémentation en assembleur :

L’addition sur plusieurs bytes, en assembleur 8086, se fait avec ADC. Le drapeau carry permet de propager les
bits de retenue (carry) d’un byte à l’autre.

La soustraction sur plusieurs bytes, en assembleur 8086, se fait avec SBB. Le drapeau carry permet de propager
l’emprunt (borrow) d’un byte à l’autre.

Le décalage de bits sur plusieurs bytes, en assembleur 8086, se fait avec RCL ou RCR. Le carry permet de
propager les MSBs ou LSBs d’un byte à l’autre.

Pour traiter les fractions, il vous faudra des variables temporaires (ou de travail) ayant 24 bits (23 bits de mantisse
+ 1 pour le 1 de la norme) + un nombre de bit égal à la différence maximum entre les exposants afin de traiter des
décalages. Comme cette différence maximum est de 8 dans le cadre du laboratoire (voir plus bas), il vous faudra
des variables de 32bits… ou des pairs de registres 16 bits.

Etienne Tremblay Page 3 2011-03-19


Caractéristiques du programme à remettre:

- Pour vous simplifier la tâche, le programme ne doit gérer que des fractions ayant des
exposants entre 124 et 131.
- La première instruction du programme doit être à l’adresse 100H. Cette instruction doit être
une instruction de saut sur 2 bytes.
- Par convention, toutes les fractions devront être représentées en format big endian.
- Par défaut, les adresses 102H à 105H de votre programme doivent contenir la première
fraction à additionner.
- Par défaut, les adresses 106H à 109H de votre programme doivent contenir la deuxième
fraction à additionner.
- Par défaut, les adresses 10AH à 10DH de votre programme doivent contenir le résultat de
l’addition.
- Votre programme doit appeler une fonction qui additionnera deux fractions. Cette fonction doit
avoir les caractéristiques suivantes :
- La fonction reçoit trois paramètres d’entrées : l’adresse de la première fraction à additionner,
l’adresse de la deuxième fraction à additionner et l’adresse où mettre le résultat de l’opération.
- La fonction ne retourne aucun paramètre.
- Il doit être possible de mettre tous les paramètres d’entrées à la même valeur. Cela équivaut à
multiplier une fraction en mémoire par 2.
- La fonction doit être propre : tous les registres doivent avoir la même valeur avant et après
l’appel de la fonction (sauf IP!!! Par ailleurs, le passage des paramètres est considéré comme
faisant partie de l’appel de la fonction).
- Les paramètres de la fonction doivent être passés par la pile.
- Pour satisfaire tous les énoncés précédents, les paramètres passés à la fonction lors de son
exécution pour évaluation devraient être 0102h, 0106h et 010Ah.
- Le programme doit contenir les noms et/ou matricules de ses concepteurs en commentaires,
dans l’entête du fichier remis.
- Le programme doit contenir plusieurs commentaires (au moins un commentaire toutes les 4
lignes). Un programme non commenté ne sera pas corrigé.

Bon travail,

Etienne Tremblay

Etienne Tremblay Page 4 2011-03-19