jeudi 19 octobre 2017

Les outils



Comme indiqué, les sources seront saisis avec Notepad++ puis transférés sur le Raspberry pour être compilés avec l’assembleur gnu as et linkés avec ld ou avec gcc. Une connexion ssh sera ouverte à partir du logiciel puTTY (remarque avec les dernières versions de Jessie, l’autorisation d’une connexion ssh n’est pas active. Il faut l’activer dans le menu de configuration du Raspberry : voir la doc de base).
Sur Notepad++, il faut aussi installer la coloration syntaxique pour l’assembleur ARM avec l’extension .s car celle-ci n’est pas prévue par défaut.
Il est possible d’effectuer une compilation sur l’ordinateur maitre (par exemple sous Windows, voir par exemple le logiciel gcc-arm-none-eabi-6-2017-q2-update-win32.exe ) mais cette solution ne me satisfait pas car il peut y avoir des différences entre les diverses librairies utilisées par les 2 systèmes. Si vous préférez cette solution et si vous transférez le programme exécutable sur le Raspberry, n’oubliez pas d’effectuer un chmod 777 nomduprogramme pour le rendre exécutable sous linux. (Je suppose que vous avez une bonne connaissance des commandes Linux de base !!!).
Normalement les logiciels as, ld et gcc sont installés en standard avec la version Raspbian. Vous pouvez vérifier la présence des logiciels par as toto  ou ld toto ou gcc toto. Si en retour vous avez le message –bash as (ou ld ou gcc) commande introuvable c’est que ces logiciels ne sont pas installés ou non accessibles. Il vous faudra télécharger les paquets nécessaires et les installer sur votre système.
Vérifions le bon fonctionnement en tapant le premier programme indiqué dans le premier chapitre sur le site de Thinkingeek :

/* programme 1  */
/* pour vérification compilation et link  */
.text             /* -- Code section */
.global main      /* point d’entrée du programme */

main:             /* programme principal */
       mov r0,#2  /*  on met 2 dans le registre r0  qui sera le code retour du programme*/
       bx lr        /* fin du programme par retour à l’adresse contenu dans lr*/
Lien vers le source du programme à télécharger

Sauvegarder le programme sous pgm1.s (l’extension .s est réservée pour les programmes en assembleur ARM) et transférer le sous un répertoire de travail du Raspberry.
Taper dans la session ssh ouverte la commande de compilation pour créer l’objet :
as –o pgm1.o pgm1.s
Vous pouvez avoir un ou plusieurs messages d’erreur (et ici ce sont surtout des erreurs de saisie faciles à corriger) sinon  vérifier par ls –l si le fichier pgm1.o vient d’être crée.
Puis lancer la commande pour le link  qui va créer le programme exécutable:
ld –o pgm1  pgm1.o –e main
Le paramètre –e indique que le point d’entrée du programme est main. Cela doit correspondre avec l’instruction .global main de notre source.
Si pas de message d’erreur, vérifier par ls –l que le programme pgm1 est bien crée et le lancer en tapant la commande : ./pgm1
Bon sang : le message « erreur de segmentation » apparait dans toute sa simplicité. Notre programme n’a que 2 instructions et nous avons déjà une erreur incompréhensible. Heureusement le chapitre 4 de l’assembleur ARM sur Thinkingeek nous explique le fonctionnement du débogueur GDB. Après quelques manipulations j’arrive à vider le contenu des registres et je vois que le registre lr sensé contenir l’adresse de retour contient 0 ce qui ne nous aide pas beaucoup.
En relisant les commentaires du chapitre 1 sur Thinkingeek, je vois qu’un correspondant propose de terminer le programme en appelant la fonction système exit. Voici le code à mettre à la place du bx lr :
   mov r7, #1 /* code fonction système EXIT */
   swi 0         /* appel fonction système */
Sauvegardons ce programme sous pgm2.s puis transfert vers le Raspberry puis compilation par as puis link par ld et lancement par ./pgm2.
Cette fois ci il n’y a pas d’erreur mais rien n’apparait !! Ah oui il faut ensuite taper echo $ ? pour afficher le code retour du dernier programme exécuté. C’est Ok, le chiffre 2 apparait bien.
Cette erreur m’intrigue et j’imagine toute sorte de raisons de cet écart avec les instructions du site : Raspberry différent, version linux différente etc..
Mais en relisant le premier chapitre, je me rends compte que le link du programme est fait avec gcc (cad le compilateur linker pour le langage C). Donc je lance le link sur le pgm1.o avec la commande :
gcc –o pgm1 pgm1.o
Puis l’exécution du programme par ./pgm1 et là miracle plus d’erreur de segmentation et le programme fonctionne.
Nos outils de travail sont maintenant prêts et nous allons continuer la découverte de l’assembleur dans les posts suivants.
Remarque : l’erreur de segmentation est l’erreur qui va revenir le plus souvent lors des tests de programme. Nous voyons qu’elle correspond à une adresse invalide contenu dans un registre et le plus souvent cela sera 00000000.
Exercices : lisez le chapitre 4 sur le deboggeur GBD et essayer toutes les commandes sur ce petit programme.
                Lisez la documentation sur l’assembleur as, le linker ld et compilateur C gcc.
                Placer des valeurs différentes dans 2 registres, faites la somme, ou  la différence ou la multiplication et sortir le résultat comme ci-dessus.

2 commentaires:

  1. Bonjour, merci beaucoup pour tout ce tutorial en français ainsi que pour votre aide. Je n'ai toutefois pas réussi à compiler sur un arm64 (pine64), pourriez-vous indiquer si c'est possible via une option (-mcpu et/ou -march) et quel paramètre lui indiquer ?

    RépondreSupprimer
  2. Bonsoir.
    Quel est exactement votre problème.
    Je suppose que le système d'exploitation de cette carte est linux.
    Avez-vous essayer de taper simplement as pour voir si l'assembleur est ok sur votre carte ?

    RépondreSupprimer