Après tous ces chapitres sur le développement en assembleur
sans OS, nous revenons à des exemples de programmes avec Linux. Dans ce
chapitre nous allons voir des routines de calcul sur des nombres entiers
doubles qui sont codés sur 64 bits soit 8 octets ce qui permet de traiter des
entiers jusqu’à 2<<63 – 1 soit : 9223372036854775807 en non signé et
+4611686018427387903 en signé.
Pour cela nous commençons par déclarer plusieurs nombres
positifs et négatifs avec la pseudo instruction .quad. et nous réservons dans
la .bbs des zones de 8 octets pour stocker des résultats intermédiaires.
Source du programme ici .
Dans le code, nous commençons par afficher par la macro
habituelle les zones mémoires pour voir le stockage des doubles : La
partie basse est dans les 4 premiers octets, la partie haute dans les 4 suivants.
Pour vérifier les calculs suivants, il nous faut commencer
par afficher correctement un double et première difficulté il nous faut écrire
une routine qui divise un double contenu dans 2 registres par 10. C’est le rôle
des routines conversionDoubleU et divisionReg64U. Puis il nous faut aussi
écrire les routines pour afficher des doubles signés : conversionDoubleS
et divisionReg64S. Les divisions utilisent un algorithme classique de division
binaire et ne divisent un double que par une valeur contenue dans un seul
registre.
Pour lire un double ou stocker un double en mémoire, nous
disposons de l’instruction ldrd r0,r1,[r2] et de l’instruction strd r0,r1,[r2]
avec bien sûr r2 contenant l’adresse mémoire du double, r0 la partie basse et
r1 la partie haute. Nous pouvons utiliser d’autres registres en condition que
le premier soit pair et que le second soit le suivant (il y a une erreur de
compilation pour r5,r8,[r2] par exemple !!).
Ensuite nous écrivons une routine de saisie d’un double à
partir de la lecture d’une chaine de caractère à l’aide du système call READ. La
conversion de la chaine stocke le double dans une zone en mémoire après avoir
vérifié le dépassement de capacité éventuel.
Les autres routines correspondent à la division, addition
soustraction multiplication signés et non signés de 2 nombres de 64 bits.
Certaines routines utilisent les doubles stockés en mémoire et d’autres dans
les registres. La difficulté est de penser à traiter les 2 registres qui
contiennent le double et à bien reporter les retenues éventuelles. Il faut
aussi veiller à bien utiliser les codes des comparaisons suivant que les
nombres traités sont signées ou non. Par exemple pour la partie basse, il faut
utiliser les codes hi (> non signé) lo (< non signé) et pour les parties
hautes gt ou lt.
Enfin le programme se termine par une extraction de racine
carrée entière par la méthode de héron et par des routines de comparaisons.
Il ne vous reste plus qu’à écrire les routines manquantes et
d’optimiser celles qui sont dans ce programme !!
Ah j’oubliais, dans le fichier des macros, j’ai ajouté une
macro qui affiche un simple libellé dans la console. Cela permet un petit gain
de temps pour incluse un libellé entre les différents tests des routines.
Aucun commentaire:
Enregistrer un commentaire