dimanche 10 novembre 2019

Chapitre 70 : Assembleur ARM 64 : tests de quelques instructions 64 bits


Maintenant, que les outils précédents sont prêts, nous allons regarder plus en détail les principales instructions disponibles en 64 bits. Le programme instrBits.s va tester les instructions de manipulations de bits. Nous commençons par les tables de vérité and, oor, eor, orn, eon et bic. Cette dernière est intéressante pour remettre des bits à zéro.
Par exemple dans la routine d’affichage mémoire, l’affichage commence toujours en début d’un bloc de 16 octets soit une adresse qui se termine par 0 hexa soit 0b0000  binaire. Pour remettre ces 4 bits à zéro j’utiliser les instructions mov x1, x2, ASR #4 puis mov x1, x1, LSL #4 alors que l’on peut avoir une seule instruction :
Bic x1,x2,0b1111     (voir l’exemple bic_bis dans le programme instrBits.s)

Ensuite nous testons les instructions lsr,lsl,ror et asr. Asr permet de diviser un nombre négatif par une puissance de 2 à faible côut. Ce test m’a perturbé car l’affichage du résultat en nombre décimal était incorrect. Après recherche je me suis aperçu que je passais dans x1 l’adresse de la zone réceptrice avec l’instruction mov x1, qAdrszZoneRec1 à la place de ldr x1, qAdrszZoneRec1. En 32 bits, le compilateur signalait une erreur mais pas en 64 bits. Dans ce cas, il charge bien une valeur dans x0 mais je n’ai pas encore trouvé à quoi elle correspond. Cela va être une source d’erreur pas facile à trouver.
Nous testons les comptages de bits à zéro ou de un  à gauche avec les instructions clz et cls puis les inversions de bits, d’octets, de demi mot et de mot et nous terminons par les remplacements de bits.
J’ai mis un exemple de calcul de valeur absolue sans utilisation d’un test !! et je termine par un test d’une routine dans laquelle il n’y une instruction qui désaligne la pile. Si vous enlevez le commentaire vous verrez apparaitre l’erreur erreur du bus !!!

Dans le second programme instMovArith.s, nous allons tester les instructions arithmétiques et move. Je commence par refaire le test de l’instruction mov x0,label pour voir à quoi correspond le résultat. Il s’avère que x0 contient maintenant le déplacement du label à partir du début de la section .text.  Si le label fait partie de la section .data, le déplacement est celui du début de cette section. Cela peut être utile de le savoir et il faudra faire quand même attention à ne pas confondre avec ldr x0,label.

Dans la suite de programme, je teste la valeur immédiate maximum acceptable dans un mov. La longueur maxi est de 16 bits soit une valeur égale à 0xFFFF soit 65535 décimal. S’il faut manipuler une valeur immédiate supérieure il faut utiliser l’instruction movk avec un déplacement de 16,32 et 48 pour positionner des tranches de 16 bits au bon endroit.
Puis je reteste l’instruction movn qui ne donne pas la valeur d’un complément à 2 mais qui est en fait l’operateur not. Par contre dans la documentation je trouve l’instruction neg qui donne bien le résultat attendu : neg x0,-5 donne 5
Ensuite, je teste l’instruction addition en vérifiant la mise à jour du flag overflow pour une valeur supérieure à 2puissance 63. Puis je teste la soustraction et la multiplication.
Curieusement pour la multiplication, il n’est pas possible d’ajouter le s pour demander la mise à jour du registre d’état et donc de vérifier l’overflow. Il faut donc recourir à une astuce : utiliser l’instruction smulh pour multiplier les parties hautes des registres et si le résultat est non nul c’est qu’il y a dépassement de capacité.
Dans le programme instrCond.s, nous allons vérifier quelques instructions conditionnelles. Tout d’abord on teste l’instruction csel qui permet de mettre dans un registre la valeur d’un deuxième ou d’un 3ième registre suivant la condition. En fait c’est un if then else mais concernant qu’une seule possibilité.
La 2ième instruction testée est cinc qui incrémente ou non un registre suivant la condition.
Puis je teste l’instruction csinc qui soit incrémente un registre soit met la valeur d’un autre.
Puis l’instruction cneg qui permet de calculer une valeur absolue en 2 instructions seulement.
Et je termine par l’instruction ccmp plus compliquée : ici je montre en 2 exemples comment vérifier si une valeur est comprise entre 2 bornes incluses puis entre 2 bornes exclues.  J’ai mis zéro pour la 3ième donnée de l’instruction car je n’ai pas bien compris son rôle.
Les sources des programmes se trouvent dans ce répertoire : 

Aucun commentaire:

Enregistrer un commentaire