jeudi 26 octobre 2017

Chapitre 5 : Saisie d'un nombre entier



Nous avons vu la saisie d’une chaine de caractères au chapitre précédent et rien n’indique dans l’appel système READ utilisé comment saisir un nombre directement récupérable dans un registre. Et non aucune instruction ne permet cela et donc c’est à nous à programmer une conversion de la chaine saisie en nombre. Avec plusieurs petites questions à résoudre : nombres négatifs, dépassement de capacité, nombres avec virgule etc. Dans ce chapitre nous n’allons pas nous occuper des nombres décimaux car je n’ai pas encore découvert cette partie sur les processeurs ARM mais ça viendra !!!.
Donc voici un programme avec une routine de conversion qui permet de saisir un nombre (positif ou négatif) et de le stocker dans un registre. Sa valeur sera donc comprise entre -1073741824 et +1073741824.
Lien vers le source du programme.
Dans ce programme, et pour simplifier toutes les routines vues précédemment ont été déportées dans le fichier routinesARM.o.
Rien de nouveau dans la section .data. dans la section bss, on ajoute une zone iValeur de 4 octets qui servira à stocker la valeur saisie en mémoire après conversion. Il faut aligner cette zone sur une frontière de double mot avec l’instruction .align 4. Je n’ai pas rencontré d’erreur si cela n’est pas fait et je pense qu’il s’agit plutôt d’une amélioration de performance du processeur.
Dans le programme principal, on retrouve les affichages et l’appel systéme pour la saisie. Après celle çi et s’il n’y a pas d’erreur nous appelons la routine conversionAtoD puis nous affichons les registres et la zone mémoire pour vérification. Enfin nous stockons la valeur retournée dans le registre r0 en mémoire avec les instructions

               ldr r1,adresse_valeur  
                str r0,[r1]

Sans d’autre précision, ces instructions travaillent sur des registres de 32 bits. Donc la première stocke dans le registre r1, l’adresse contenue dans la zone adresse-valeur et la seconde stocke le contenu du registre r0 à l’adresse contenue dans r1. Comprenez bien ces instructions parce que vous allez les utiliser souvent. Il était possible de faire un accès direct à la zone par :

ldr r1,= iValeur
str r0,[r1]

Maintenant voyons la sous-routine de conversion de la chaine de caractères en valeur numérique. Après les sauvegardes habituelles des registres, nous initialisons les registres qui vont être utilisés. Puis nous trouvons une boucle pour sauter tous les caractères blancs pouvant se trouver au début de la saisie. S’il n’y a que des blancs et que nous rencontrons le caractère 0 binaire ou 0A nous allons directement en fin de routine. Sinon au premier caractère non blanc rencontré nous vérifions s’il ne s’agit pas du caractère – et dans ce cas nous mettons 1 dans le registre r6. Puis nous continuons par une boucle qui va contrôler si les caractères sont bien numériques en ascii et va enlever la valeur 48 pour retrouver un chiffre binaire qui sera ajouté au résultat précédent. Mais d’abord il faudra multiplier ce résultat précèdent par 10 puisque chaque chiffre saisi entraine un résultat 10 fois plus grand.
Nous vérifions aussi que le registre r0 ne dépasse pas la valeur maximum car le processeur n’indique en rien ce dépassement. Il y a bien un drapeau v pour overflow mais celui ci n’est pas mis pour la multiplication : curieux non ?
Puis nous continuons la boucle d’analyse jusqu’à rencontrer le caractère 0 binaire ou 0A pour la terminer.
Il nous reste une dernière petit opération, c’est de comparer le registre r6 à 1 ce qui indique que la saisie est un nombre négatif et donc il faut multiplier le résultat par -1 pour avoir un résultat correct. Remarquez que l’instruction mul r0,r0,r1 entraine une erreur de compilation alors que l’instruction mul r0,r1,r0 est correcte.
Cette sous routine peut être améliorée pour la vérification des caractères saisies car par exemple 12aa24 donne le résultat 1224 (décimal)  dans le registre r0.
Exercice : essayer de nombreux nombres positifs ou négatif.
                Que se passe t-il si vous appuyer sur d’autres touches du clavier (tab ou F1 ou les flèches   de direction).
                Effectuer la saisie de 2 nombres, calculer leur produit et afficher le résultat
               Modifier le programme pour saisir une série de nombres (donc en nombre variable) et calculer leur somme.

Aucun commentaire:

Enregistrer un commentaire