 
Pour ceux qui ont manqué les prolégomènes de cette monumentale introduction à l'assembleur des processeurs ARM sur RISC PC, sachez que vous pouvez toujours vous replonger dans l'acte zéro, paru dans le numéro zéro de notre modeste bulletin de liaison de l'ARMada. Ce numéro est disponible gratuitement (sauf, bien entendu, les éventuels frais d'envoi) auprès du siège de l'association , sur simple demande (à ce propos... n'oubliez pas d'adhérer, hein?).
Qu'allons-nous faire, aujourd'hui ? Et bien, mon jeune ami, nous allons apprendre à compter! Si, si... Il y a un début à tout, non? De plus, comme c'est en forgeant qu'on devient forgeron...
 ;Premiere addition en assembleur sur ARM
R0      RN 0                     ;Definition reg.0
R1      RN 1                     ;Definition reg.1 
R2      RN 2                     ;Definition reg.2
LMAX    EQU 1                    ;1 chiffre max.
        AREA PREMADD ,CODE        ;Zone principale
        ENTRY                    ;Point d'entree
        MOV R0,#1                ;R0=1
        MOV R1,#1                ;R1=1
        
        ADD R0,R0,R1             ;R0=R0+R1
        ADR R1,RESULT            ;Adresse de Result
        MOV R2,#LMAX             ;nb max. chiffres
        SWI &28                  ;OS_BinaryToDecimal
        
        ADR R0,MOUT              ;Adresse message
        SWI 2                    ;OS_Write0
        
        MOV R0,R1                ;Adresse de Result
        MOV R1,R2                ;R1=R2 (nb car.)
        SWI &46                  ;OS_WriteN
        SWI &11                  ;OS_Exit 
MOUT    DCB "Resultat: ",0       ;A afficher
RESULT  % LMAX                   ;Res. Lmax octets
        END                      ;Fin d'assemblage
A présent, sauvegardez le fichier-source ``myadd'', faites-le mouliner un coup par l'assembleur, puis par le linkeur, de façon à produire un exécutable. Puis vous n'aurez plus qu'à le déclencher... Ce qui entraînera, si tout s'est bien déroulé, l'ouverture d'une fenêtre affichant:
Resultat: 2 Press space or click mouse button to exit . . ....Hmm, c'est bon! Avant de passer à la suite de l'article, je vous autorise à vous éponger le front, pousser un soupir de soulagement (``Pff! Ca marche!''), bondir de joie, réveiller tout l'immeuble, le quartier, et enfin à recommencer cent fois de suite toute l'opération, de la main gauche (parce que la droite sera certainement occupée)...
Ca y est ? C'est fini ?
Bon. Maintenant, il va falloir retrouver notre sang froid. Tâchons un peu de comprendre tout ce charabia...
;Premiere addition en assembleur sur ARMComme nous l'avons déjà vu dans l'acte zéro, une ligne d'assembleur commençant par un point-virgule est un commentaire, et n'a donc aucune conséquence dans l'exécutable résultant, puisque ignorée purement et simplement lors de la compilation.
R0 RN 0 ;Definition reg.0 R1 RN 1 ;Definition reg.1 R2 RN 2 ;Definition reg.2La directive RN, en début de code-source, permet de définir le symbole par lequel le n-ième registre (Nous avons vu dans l'acte zéro qu'un registre est une des mémoires internes du processeur, et qu'il permet de stocker un nombre entier pour ``travailler'' dessus. Ce programme donne , avec l'addition , un exemple de traitement de données dans le processeur) sera désigné. Ici, au lieu d'appeler les registres par des noms exotiques du genre ``TOTO'', je me contente d'aller au plus simple: le registre numéro x portera le nom Rx.
LMAX EQU 1 ;1 chiffre max.Ah ! Voici la définition d'une constante. Une constante est un symbole qui porte une valeur numérique (ici, c'est 1), et la constante est LMAX. Lors de l'assemblage, dans toutes les instructions où le symbole LMAX apparaîtra, sa valeur, définie ici, lui sera substituée. Dans ce programme, LMAX est la longueur maximum de la chaîne de caractères dans laquelle le résultat de l'addition sera écrit (en chiffres), avant d'être envoyé à l'écran. L'intérêt de la chose est que vous pourrez vous amuser ultérieurement à modifier le source pour que le programme additionne autre chose que 1 et 1, et donc le résultat pourra faire plus de un chiffre de long. Tout ce que vous aurez à faire pour que cette longueur soit respectée , c'est de modifier LMAX.
        AREA PREMADD,CODE        ;Zone principale
La directive AREA déclare au compilateur une zone dont le
nom est PREMADD et qui contiendra du CODE.
        ENTRY                    ;Point d'entree
Cette directive permet de déterminer que, lors de l'exécution, la première
instruction exécutée est celle qui suit.
        MOV R0,#1                ;R0=1
        MOV R1,#1                ;R1=1
L'instruction MOV affecte un registre de destination. Sa syntaxe la plus
simple est: MOV Rn,#x, c'est à dire que l'entier de 32 bits (En fait , de 8 bits ``extensibles'' sur les 32 du registre , mais nous y
reviendrons ultérieurement) x
est écrit dans le registre Rn. Ici, les deux registres R0 et
R1 sont chacun affectés de la valeur entière 1. Vous pouvez vous
amuser à modifier ces valeurs dans le source, de sorte que le résultat
affiché ne sera pas toujours 2.
        
        ADD R0,R0,R1             ;R0=R0+R1
Voici enfin l'instruction d'addition! Sa syntaxe la plus simple est:
        ADD Rc,Ra,Rb
ce qui signifie que les registres Ra et Rb
seront additionnés, et que leur somme sera affectée au registre Rc.
Ici, les registres R0 et R1 sont additionnés, leur somme est
écrite dans le registre R0, qui, de ce fait, perd son ancienne
valeur.
        ADR R1,RESULT            ;Adresse de Result
L'instruction ADR permet d'écrire l'adresse que pointe le label
RESULT, défini un peu plus loin dans le listing, dans le registre R1.
        MOV R2,#LMAX             ;nb max. chiffres
Tiens tiens... Où l'on voit resurgir le symbole LMAX défini au tout
début du listing. Ici, donc, sa valeur est affectée au registre R2.
ATTENTION ! N'oubliez surtout pas le signe ``#'' devant LMAX!
        SWI &28                  ;OS_BinaryToDecimal
La fonction du système d'exploitation &28 (40, en décimal), répondant au joli nom de
 OS_BinaryToDecimal, permet de convertir le nombre binaire
contenu dans le registre R0 en chaîne de caractères dont l'adresse
est spécifiée dans le registre R1, et de longueur maximale
précisée dans le registre R2. Ici, le résultat de l'addition,
contenu dans le registre R0, sera converti en nombre ASCII à partir
de l'adresse RESULT, définie plus bas, avec LMAX chiffres de
long au maximum. ATTENTION: après l'exécution de cette fonction,
la valeur du registre R2 aura été modifiée: au lieu de contenir
le nombre maximum de caractères, le registre R2 contiendra le nombre
effectif de caractères!
        
        ADR R0,MOUT              ;Adresse message
L'adresse du message commençant à partir du label MOUT, défini
plus bas, est écrite dans le registre R0.
        SWI 2                    ;OS_Write0
La fonction du système d'exploitation 2, appelée OS\_Write0,
permet d'écrire à l'écran la chaîne de caractères commençant
à l'adresse pointée par le registre R0, et terminée par un
octet nul. Ici, c'est de la chaîne de caractères commençant au label
MOUT qu'il s'agît, en l'occurence, c'est ``Resultat: '' qui
sortira à l'écran.
        
        MOV R0 ,R1                ;Adresse de Result
        MOV R1 ,R2                ;R1=R2 (nb car.)
Voici une deuxième façon de se servir de l'instruction MOV. Cette
fois, ce n'est pas un nombre littéral qui est écrit dans le registre de
destination, mais le contenu d'un autre registre. Ici, le contenu de R1
est écrit dans R0, puis celui de R2 est à son tour écrit
dans R1. Si nous nous souvenons de ces valeurs, cela revient à
transférer la valeur de l'adresse de la chaîne de caractères
représentant le résultat de l'addition dans R0, et le nombre de
caractères de cette chaîne dans R1.
        SWI &46                  ;OS_WriteN
La fonction du sytème d'exploitation 46 (70, en décimal) permet
d'écrire à l'écran la chaîne de caractères qui commence à l'adresse
pointée par R0 et de R1 caractères de long. Ici, c'est la
chaîne de caractères résultant de la conversion Binaire-->Décimal
ASCII que nous venons d'effectuer qui sera affichée.
        SWI &11                  ;OS_Exit 
Voilà. Une fois ceci fait, il ne restera plus qu'à sortir du programme, au
moyen de la fonction du système d'exploitation 11 (17, en décimal),
que nous connaissons déjà depuis l'acte zéro.
MOUT DCB "Resultat: ",0 ;A afficherVoici une ligne qui nous en rappelle une autre, vue dans l'acte zéro: ici, nous déclarons un label, MOUT, et nous forçons le compilateur à écrire directement la chaîne de caractères ``Resultat: '', suivie d'un octet nul, dans le fichier exécutable.
RESULT % LMAX ;Res. Lmax octetsIci est défini le label RESULT. Il est suivi de la directive % (oui, oui, vous avez bien vu: le signe ``%''), qui permet de reserver un certain nombre d'octets nuls dans le fichier exécutable. Le nombre d'octets à réserver est spécifié juste après. Ici, c'est encore le fameux nombre symbolisé par LMAX, que vous pouvez modifier au début du fichier-source.
        END                      ;Fin d'assemblage
Voici enfin la directive qui arrête la compilation. Tant mieux. Je n'en
pouvais plus.
Jetons un coup d'oeil à côté, sur le programme du petit frêre, réalisé en BASIC: c'est beau, c'est plein de couleurs! Revenons alors à notre minable affichage ``1+1=2''. Lequel préférez-vous? Le Tchika-tchika-boum en BASIC? Probablement.
Soyons francs: vous ne pourrez arriver à des résultats de cet ordre qu'au bout d'un long et difficile apprentissage, qui commence à peine. Mais à la fin, si vous savez vous accrocher, réfléchir aux difficultés, poser des questions sur ce qui vous embarrasse, et surtout m'engueuler quand je ne suis pas assez clair, vous serez à même de faire jouer la Marseillaise au disque dur. Si, si, ça viendra, c'est une question de patience, mais, plus encore, de persévérance!