Au chapitre précédent, nous avons vu quelques exemples d’additions,
voyons maintenant quelques exemples de soustractions (ne pas oublier le s
pour mettre à jour les drapeaux): cas 1
calcul de 4 – 10, cas 2 calcul de 10 – 6 cas 3 calcul de valeur mini négatif –
5 (anomalie : c’est une valeur positive et le drapeau overflow est bien à
1). Source du programme
Puis voici la multiplication simple mul et la
multiplication avec ajout d’un registre mla.
Vous constatez dans ce cas qu’aucun drapeau ne peut être
examiné, ce qui est curieux !! En effet comment savoir si le résultat
n’est pas en overflow. Mais heureusement l’assembleur propose l’instruction
umull qui permet d’avoir le résultat dans 2 registres, un contiendra les 32
bits bas et l’autre les 32 bits hauts. En testant si les 32 bits hauts sont
différents de zéro, on peut savoir si la multiplication non signée est en
overflow. Pour la multiplication signée il faut si l’égalité dans les
instructions suivantes est fausse il y a overflow:
umulls r0,r1,r2,r3 @ r0 contiendra la partie basse et r1 la
partie haute
asr
r2,r0,#31
cmp
r2,r1
Il existe d’autres instructions de multiplication mais je
n’en ai pas trouvé l’usage.
Et la division ?
comme je l’ai déjà indiqué, sur mon raspberry avec le processeur ARM1176JZF-S
la division n’est pas disponible. Il faut donc utiliser les routines décrites
au chapitre 15 de http://thinkingeek.com et dont voici quelques variantes dans
ce programme. J’ai aussi testé le temps d’exécution et j’ai trouvé que le temps
de la routine faisant intervenir la division en virgule flottante donne de bons
résultats. Dans le chapitre en question, l’auteur donne aussi des exemples pour
diviser par une constante : par exemple 3 ou 5 ou 10 en utilisant un
nombre magique.(voir le site http://www.hackersdelight.org/
qui donne des extraits d’un livre avec des idées intéressantes).
Cette voie est très
intéressante et il faut que je vérifie le temps d’exécution.
Dans ce deuxième programme, nous effectuons quelques tests
de multiplications et de divisions pour voir les résultats en non signée et
signée ; Notez l’utilisation de l’instruction rsb pour multiplier une
valeur par une puissance de 2 – 1 (par exemple 7,31,63 etc )
Aparté : beaucoup d’articles sur internet concernent
l’optimisation des programmes en assembleur. Hormis des routines particulières
qui doivent être exécutées des millions de fois, il n’y a pas lieu dans nos
exemples de chercher à optimiser le temps d’exécution. Pareil pour la taille
des programmes qui se chiffre ici en kiloOctets et que l’on dispose de mégaoctets
de mémoire. Il me parait plutôt judicieux d’optimiser le nombre de registres
utilisés dans une routine (car il n’y a que 11 registres disponibles) et de
réduire le risque d’erreur en écrivant des routines lisibles et
compréhensibles.
Aucun commentaire:
Enregistrer un commentaire