mercredi 30 octobre 2019

Chapitre 67 : assembleur arm 64 : affichage d’un registre en base 2


Maintenant que nous savons afficher un texte, nous pouvons écrire une routine qui va afficher un registre en base 2, ce qui va nous permettre d’effectuer quelques vérifications sur l’assembleur ARM 64 bits.
Mais dans le précédent chapitre, j’ai oublié de mentionner la documentation sur l’arm64. Donc nous trouvons la bible ici (5000 pages !!!) : https://static.docs.arm.com/ddi0487/a/DDI0487A_j_armv8_arm.pdf?_ga=2.21860476.697819718.1572029197-1839848267.1555097605
Et une synthèse des instructions et quelques exemples : https://modexp.wordpress.com/2018/10/30/arm64-assembly/. Par contre je n’ai pas trouvé de synthèse au format pdf comme celle pour le 32 bits.
Et une autre précision : j’ai ajouté le script de compilation avec as et du link avec ld ici https://github.com/vincentARM/ARMassembly64/blob/master/Debut/compil64

 Revenons à notre routine. Nous trouvons une première instruction stp x0,lr,[sp,-64]! qui fait descendre l’adresse de la pile de 64 octets puis qui stocke les 2 registres r0 et lr aux adresses sp et sp + 8 (Ne pas oublier le ! qui indique que la pile doit être mise à jour). Puis une deuxième instruction stp x5,x6,[sp,48] qui stocke les 2 registres aux adresses sp+48 et sp+64 etc. Ces instructions remplacent les push et nous retrouvons en fin de routine les instructions ldp qui restaurent les valeurs d’origine des registres (en remplacement des pop).
Dans mes routines, je sauvegarde tous les registres pour que celles-ci soient le plus neutres possible !!!
 Ensuite il faut tester chaque bit du registre x0 pour afficher sa valeur 0 ou 1. Hélas il n’existe plus d’instruction lsrs qui permettait de décaler le registre d’une position à gauche et de récupérer la valeur du bit dans le registre carry. Il a fallu trouver une autre solution : déplacer un bit 1 en fonction du contenu du registre puis faire un tst pour tester la valeur du bit du registre x0 se trouvant à cette position. En fonction du résultat on copie le caractères 0 ou 1 dans un registre 32 bits pour le stocker dans la zone à afficher. Attention, les instructions lsr, lsl, asr et ror ne s’appliquent qu’avec des valeurs immédiates. Pour mettre un registre comme valeur de shift,il faut utiliser les instructions lsrv, lslv, asrv et rorv.
Vous remarquerez qu’il n’est plus possible d’utiliser les instructions sous la forme add x2,#1 mais qu’il faut utiliser add x2,x2,#1.

Cette routine sert à tester que le registre x1 est bien sauvegardé dans les routines, à vérifier que le registre w0 n’est que la partie basse d’un registre 64 bits et attention il faudra toujours s’en souvenir pour éviter des anomalies !!
Je teste aussi l’instruction ubfx qui permet d’extraire une série de bits situé à une position donnée (hélas il me semble que le nombre et la position ne peuvent être que des valeurs immédiates).
Et je teste aussi le résultat d’une nouvelle instruction eon.

En lisant la documentation sur les nouvelles instructions, je trouve l’instruction csel qui remplace une partie des instructions conditionnelles. Dans le programme affbinaire1.s : https://github.com/vincentARM/ARMassembly64/blob/master/Debut/affbinaire1.s je modifie les instructions qui mettent 1 ou 0 suivant le bit à l’aide de branchement pour les remplacer par l’instruction csel  x6,x7,x8,eq. Cela évite les branchements mais il faut utiliser 2 registres supplémentaires x7 x8 pour stocker les valeurs 48 et 49 !!

Aucun commentaire:

Enregistrer un commentaire