mercredi 4 avril 2018

Chapitre 23 : Opérations arithmétiques entières


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