UNIVERSITE Joseph FOURIER, Grenoble AFONSO Nicolas
U.F.R. d’ Informatique et Maths. Appliquées VIVIEN Jonathan
Licence Sciences et Technologie MIN L2
Parcours INM, INF, IAG, BIN 10/03/2010
UE INF241 : Introduction aux Architectures Logicielles et
Matérielles
Feuilles de compte-rendu pour le travail pratique des séances 5 et 6: codage
des structures de contrôle
Introduction: dans la continuation de notre apprentissage en langage d'assembleur, nous allons
aujourd'hui apprendre à coder et résoudre des algorithmes en utilisant des structures de contrôle.
Vous trouverez en fin de ce compte-rendu le listing de nos programmes.
1/ Accès à un tableau
Nous commençons ce TP en travaillant sur les tableaux. On complète le fichier tableau.s afin de
réaliser les dernières affectations.
Nous rencontrons déjà un message d'erreur lorsque nous essayons de le compiler:
tableau.s: Assembler messages:
tableau.s:16: Error: invalid constant (14d) after fixup
tableau.s:24: Error: invalid constant (22b) after fixup
Ce souci vient du fait qu’on ne peut passer toutes les valeurs immédiates que l’on veut dans nos instructions
d’affectation. On pourra consulter la page 9 de la doc. Technique pour plus d’informations. Après un
changement mineur dans notre énoncé (on veut désormais affecter dans notre tableau les valeurs 11, 22,
33,44, 55), la compilation se passe sans problèmes. Attention tout de même à ne pas oublier de s’aligner sur
une adresse multiple de 4 (commande .balign 4) avant la déclaration de réservation de mémoire .skip ! Nous
avons fait cet oubli, repéré grâce au débogueur (que nous allons voir juste après) ; en résultait une non
exécution du programme jusqu’au bout.
Nous allons maintenant apprendre à nous servir du déboguer gdb, dans le but de suivre l’exécution de nos
programmes plus en détail, pas à pas.
Suivons l’exécution de notre programme tableau.s grâce à cet outil. La commande info reg nous permet de
connaître à tout moment les valeurs stockées dans tous les registres.
Regardons ce qu’on obtient en tout début de programme (aucune instruction n’a été exécutée).
info reg
r0 0x1 1
r1 0x1ffff8 2097144
r2 0x0 0
r3 0xffffffff 4294967295
r4 0x1 1
r5 0x1ffff8 2097144
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x200100 2097408
r11 0x0 0
r12 0x1fffe8 2097128
sp 0x1ffff8 0x1ffff8
lr 0x81fc 33276
pc 0x8218 0x8218 <main>
fps 0x0 0
cpsr 0x40000013 1073741843
Aucune valeur particulière, nous sommes d’accord. Si maintenant nous réutilisons cette commande après
avoir exécuté les trois premières instructions du programme (on les rappelle) :
ldr r0, ptr_debutTAB @ on charge dans r0 l'adresse de la premre case
mov r1, #11 @ r1 <- 11
str r1, [r0] @ on sauvegarde dans la case courante du tableau la valeur de r1
info reg
r0 0x12ec0 77504
r1 0xb 11
r2 0x0 0
r3 0xffffffff 4294967295
r4 0x1 1
r5 0x1ffff8 2097144
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x200100 2097408
r11 0x0 0
r12 0x1fffe8 2097128
sp 0x1ffff8 0x1ffff8
lr 0x81fc 33276
pc 0x8224 0x8224 <main+12>
fps 0x0 0
cpsr 0x40000013 1073741843
On constate que notre programme fonctionne bien : on a chargé dans r0 l’adresse de la première case de
notre tableau et la valeur 11 dans r1.
On peut donc pour finir l’analyse de ce premier programme noter les valeurs successives de r0 :
77504, 77508, 77512, 77516, 77520.
De même pour le contenu de la mémoire à partir de l’adresse debutTAB en début de programme et après
l’exécution de toutes les instructions (on utilise la commande x/5w &debutTAB) :
x/5w &debutTAB
0x12ec0 <debutTAB>: 0x0000000b 0x00000016 0x00000021 0x0000002c
0x12ed0 <debutTAB+16>: 0x00000037
On retrouve l’adresse de la première case du tableau (débutTAB) : 0x12ec0, 0x0000000b en hexadécimal est
bien égal à 11 en décimal, 0x00000016 = 22, 0x00000021 = 33, 0x0000002c = 4. La dernière case du tableau
quand à elle contient bien la valeur 55 (codé en hexadécimal par 0x00000037) et est bien à l’adresse
0x12ed0 (soit debutTAB +16).
2/ Codage d’une itération
Regardons maintenant comment procéder pour coder une itération. On veut créer un programme ayant le
même résultat que précédemment, mais cette fois-ci nous voulons utiliser une itération pour être bien plus
efficace (imaginez donc devoir affecter 500 cases de tableau, à 3 instructions par affectation, il nous faudrait
taper au minimum 1 500 lignes de code !).
Ce programme est déjà réalisé, cest le fichier iteration.s. Grâce à gdb, regardons quelles sont les valeurs
contenues à chaque itération dans les registres r0 et r2:
r0: ce registre doit contenir, d'après l'algorithme donné, l'adresse courante de la case de notre tableau que lon
souhaite affecter. r0 prend pour valeurs successives : 77484 (debut_TAB+0*4), 77488 (debut_TAB +1*4),
77492 debut_TAB + 2*4), 77496 (debut_TAB + 3*4), 77500 ( debut_TAB + 4*4)
r2: ce registre doit contenir, d'après l'algorithme donné, la variable dincrémentation. r2 prend pour valeurs
successives : 0, 1, 2, 3, 4, 5
La valeur contenue dans r2 à la fin de l’itération, c’est-à-dire lorsque le contrôle est à l’étiquette fintq est
donc 5 (normal car on veut réaliser 5 fois notre affectation).
Supposons maintenant que l’algorithme soit écrit avec tant que i <= 4 au lieu de tant que i <> 5. Le tableau
contiendra les mêmes valeurs à la fin de l’itération ! En effet dans cette deuxième version on va bien réaliser
5 fois notre affectation : pour i=0, 1, 2, 3, 4. Exactement comme dans notre premier algorithme. On décide de
coder avec le nouvel algorithme jusquà la fin de cette partie.
Supposons que le tableau soit maintenant un tableau de mots de 16 bits. On modifie le programme qui
devient iteration2.s (voir partie listing). Il nous suffit juste de prendre en compte que chaque case de notre
tableau ne fait plus que 2octets (car 16bits = 2octets) : on réserve donc moins de place en moire en but
de programme, on ne multiplie i que par 2 à chaque itération.
Même chose pour un tableau d’octets. Dans ce cas, chaque case ne fait plus quun seul octet. Voir le
programme iteration3.s
3/ Calcul de la suite de “Syracuse”
On désire désormais dans cette troisième partie créer un programme en assembleur qui nous calcule les n
premiers termes de la suite de Syracuse.
Donnons pour commencer les valeurs de la suite de Syracuse pour U0 = 15, calculées à la main: U0=15,
U1= 46, U2=23, U3= 70, U4=35, U5= 106, U6= 53,U7= 160, U8= 80, U9= 40, U10= 20, U11= 10, U12=5
U13= 16, U14= 8, U15= 4, U16= 2, U17=1, U18=4, U19=2, etc... On remarque que cette suite converge vers
1 avec un cycle de 3.
Pour coder ce programme il nous a fallu tout simplement suivre lalgorithme et les indications fournies dans
le poly (trop facile). On se limitera à calculer les 50 premiers termes de cette suite.
On vérifie sous gdb le bon déroulement de notre programme :
r4 : ce registre va nous servir de compteur du rang de la suite. r4 prend pour valeur successives : 0, 1, 2, 3, 4,
5, .. 17. On a bien retrouvé que notre suite converge vers 1 à partir du 17ème terme.
r0 : ce registre contient à linitialisation du programme la valeur quon attribue au premier terme (U0) de la
suite (ici 15). r0 est ensuite modifié selon lalgorithme de notre programme. Cest donc la valeur courante de
la suite. r0 prend bien pour valeurs successives les mêmes nombres que lon a calculé à la main un peu plus
haut : 15, 46, 23, 70, ..,1
r3 : ce registre va nous servir de comparaison. On continue notre boucle tant que la valeur courante de la
suite (contenue dans r0) est difrente de 1. r3 contient la valeur 1 et nest pas modifié durant lexécution du
programme.
La vérification sous gdb nous à permis de vérifier le bon fonctionnement de notre programme. Nous
réaliserons dans la dernière partie de ce TP un autre programme qui calculera des valeurs de suite, mais nous
utiliserons les fonctions daffichage, ce qui nous permettra derifier lexactitude de notre programme sans
utiliser gdb et taper à maintes et maintes reprises -s (la commande sous gdb pour passer à linstruction
suivante). Passons maintenant au gros programme de ce TP
4/ Tables de multiplication
On souhaite désormais réaliser un programme qui affiche un tableau avec les tables de multiplication de 1 à
10 suivant l'exemple donné dans le polycop.
Pour réaliser celui-ci il nous faudra utiliser deux boucles itératives imbriquées ( une pour le parcours des
lignes et une autre pour celui des colonnes ).
En s'inspirant de l'algorithme donné en page 5 du polycopié et en travaillant avec thode ( utilisation de
nombreuses étiquettes, de schémas pour s'y retrouver ), la réalisation ne nous à pas trop donné de problèmes.
Nous avons essayé detailler aux maximum, par des commentaires, notre programme ( voir partie listing ).
Pour l'affichage nous avons dû jouer entre les EcrChn et EcrChaine (problème relaté avec plus de précisions
au programme suivant). A l'exécution de celui-ci on obtient bien le résultat recherché:
arm-elf-run tabmult
| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10|
|---|---|---|---|---|---|---|---|---|---|
| 2| 4| 6| 8| 10| 12| 14| 16| 18| 20|
|---|---|---|---|---|---|---|---|---|---|
| 3| 6| 9| 12| 15| 18| 21| 24| 27| 30|
|---|---|---|---|---|---|---|---|---|---|
| 4| 8| 12| 16| 20| 24| 28| 32| 36| 40|
|---|---|---|---|---|---|---|---|---|---|
| 5| 10| 15| 20| 25| 30| 35| 40| 45| 50|
|---|---|---|---|---|---|---|---|---|---|
| 6| 12| 18| 24| 30| 36| 42| 48| 54| 60|
|---|---|---|---|---|---|---|---|---|---|
| 7| 14| 21| 28| 35| 42| 49| 56| 63| 70|
|---|---|---|---|---|---|---|---|---|---|
| 8| 16| 24| 32| 40| 48| 56| 64| 72| 80|
|---|---|---|---|---|---|---|---|---|---|
| 9| 18| 27| 36| 45| 54| 63| 72| 81| 90|
|---|---|---|---|---|---|---|---|---|---|
| 10| 20| 30| 40| 50| 60| 70| 80| 90|100|
|---|---|---|---|---|---|---|---|---|---|
Victoire !
5/ Calcul des nombres de la suite de Fibonacci
Pour finir ce TP, nous allons créer un programme qui va nous permettre de calculer les n premiers termes de
la suite de Fibonacci. Pour nous guider, on nous fournit un programme fibonacci.c (donc en langage c) sur
lequel nous devons nous appuyer pour réaliser notre programme homologue en langage d'assemblage ARM.
Le principe de réalisation va être d'utiliser des itérations, et de conserver les valeurs déjà calculées dans un
tableau.
rifions tout d'abord que le programme « modèle » fibonacci.c fonctionne bien. L'exécution de celui-ci
nous donne:
./fib
indice = 0, valeur = 0
indice = 1, valeur = 1
indice = 2, valeur = 1
indice = 3, valeur = 2
indice = 4, valeur = 3
indice = 5, valeur = 5
indice = 6, valeur = 8
indice = 7, valeur = 13
indice = 8, valeur = 21
indice = 9, valeur = 34
indice = 10, valeur = 55
indice = 11, valeur = 89
indice = 12, valeur = 144
indice = 13, valeur = 233
indice = 14, valeur = 377
indice = 15, valeur = 610
indice = 16, valeur = 987
indice = 17, valeur = 1597
indice = 18, valeur = 2584
indice = 19, valeur = 4181
indice = 20, valeur = 6765
indice = 21, valeur = 10946
indice = 22, valeur = 17711
indice = 23, valeur = 28657
indice = 24, valeur = 46368
indice = 25, valeur = 75025
indice = 26, valeur = 121393
indice = 27, valeur = 196418
indice = 28, valeur = 317811
indice = 29, valeur = 514229
indice = 30, valeur = 832040
indice = 31, valeur = 1346269
indice = 32, valeur = 2178309
indice = 33, valeur = 3524578
indice = 34, valeur = 5702887
indice = 35, valeur = 9227465
indice = 36, valeur = 14930352
indice = 37, valeur = 24157817
indice = 38, valeur = 39088169
indice = 39, valeur = 63245986
indice = 40, valeur = 102334155
1 / 7 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !