Vous êtes sur la page 1sur 5

COMPTE-RENDU

TP2 : C implémenté en Assembleur

INDP2-B

Realisé par :
Saidani Wael
Jmour Mohamed

1
TP2 : C implémenté en Assembleur
Objectif:
Lors de ce TP, vous aller :

 Compiler un code écrit en langage C


 Analyser le code assembleur ainsi que le fichier Map générés

Etapes à suivre :
1. Démarrer le programme µVision
2. Ouvrir le projet CinAsmLabList, sélectionner le menu Project, sélectionner la commande
« Open project »
3. Vérifier que le compilateur est configuré pour générer les fichiers listing du code assembleur
(Option -> listing -> C compiler Listing) avec un maximum d’optimisation (Option -> C/C++ ->
Optimization level3 (-O3))
4. Compiler le programme et examiner les fichiers listing générés (dans le répertoire « lst »)
pour pouvoir répondre aux questions du TP.

Analyse de la fonction list_init


Dans le répertoire « lst » ouvrir le fichier main_non_const_list.txt.

5. Quel est le contexte sauvegardé (s’il y en a un) après l’entrée dans la fonction list_init ?

 Les contextes sauvegardés sont :


 Le registre R4
 LR : Link registre

PUSH {r4,lr}

6. Quelle est l’instruction qui restore le contexte et assure le retour au programme appelant ?

 La commande qui restore le contexte et assure le retour au programme appelant {POP r4 pc}

7. Quel registre est utilisé comme compteur pour la boucle « for » ?

 Le registre qui joue le rôle d’un compteur pour la boucle « for » est r0.
On fait l’initialisation de ce registre à 0 à l’aide de la commande {MOVS r0, #0} .Puis on
l’incrémente à chaque fois par 1 à travers l’instruction {ADDS r0,r0, #1}

2
8. Quelles sont les instructions utilisées pour exécuter l’opération « i * 2000 » ? Expliquer leurs
fonctionnements ?

 Les instructions utilisées sont :


MOV r2,#0x7
MULS r2,r0,r2
Pour la première instruction on fait l’initialisation du registre r2 par 2000 (=0x7d0 en
hexadécimal). Puis, on multiplie (une multiplication signée) le contenu du registre r2 par le
contenu du registre r0 où on stocke le compteur i.

9. Quelles sont les instructions utilisées pour accéder à l’opérande offset[i] ? Expliquer leurs
fonctionnements ?

 LDR r3, |L1.112|


Cette instruction est utilisée pour charger l’adresse de l’offset qui est ||.data||. r3 et qui
pointe sur le début de l’offset
 LDR r4, [r3, r0, LSL #2]
L’adresse de début du tableau est la suivante : contenu de r3 +4*Nombre de colonne. En fait,
l’entier est codé sur 32bits (DCD). Or, l’offset est un tableau d’entiers et chaque case mémoire
a pour taille 1octet donc chaque case de l’offset a pour taille 4 cases mémoire.

Analyse de la fonction list_find


Dans le répertoire « lst » ouvrir le fichier main_non_const_list.txt.

10. Quel est le contexte sauvegardé (s’il y en a un) après l’entrée dans la fonction list_find ?

 Il n’y aucun contexte sauvegardé puisque BX lr est utilisé.

11. Quelle est l’instruction qui restore le contexte et assure le retour au programme appelant ?
Pourquoi elle est différente par rapport à la fonction list_init ?

 La commande qui restore le contexte et assure le retour au programe appelant est BX lr.

12. Quel est le registre contenant l’argument « Key »?

 Le registre est r1.

3
13. Quelles sont les instructions utilisées pour exécuter la comparaison dans la boucle? Expliquer
leurs fonctionnements ?
 MOVS r0, #0 ; le registre r0 est initialisé à 0.
ADDS r0, r0,#1 ; r0=r0+1 .
CMP r0, #0Xa ; comparer la valeur de i à la valeur de nombre d’éléments du tableau qui est
égal à 10 (= 0xa en hexadécimal)
BCC |L1.52| ; si la valeur de i est inférieure à 10 alors on reprend la boucle sinon on sort de la
boucle.

Analyse le fichier MAP (programme par défaut)


Dans le répertoire « lst » ouvrir le fichier List.map.

14. Examiner la table des symboles (Global Symbols) puis compléter le tableau suivant :

Symbole Adresse de début Taille

Main 0x080009e5 34

list_init 0x0800099d 44

list_find 0x080009c9 28

List 0x20000048 40

Offset 0x2000001c 40

15. Quelle est la taille réservée pour la STACK ?

 0x200002d0 - 0x00000400 Zero RW 320 STACK startup_stm32f407xx.o


Size =0x00000400 =1024bits.

16. Examiner la section (Image component sizes) puis remplir le tableau suivant pour le fichier
main.o :

Code Data RO data RW data ZI data debug

Non const offset 116 10 0 40 40 1475

Analyse le fichier MAP (programme après modification)


Changer le code source en déclarant la variable offset comme « const » puis compiler de nouveau le
programme.

4
17. Examiner la table des symboles (Global Symbol) puis compléter le tableau suivant, Identifier
les changements par rapport au tableau de la question 14 et expliquer leurs causes :

Symbole Adresse de début Taille

Main 0x080009e5 34

list_init 0x0800099d 44

list_find 0x080009c9 28

List 0x20000020 40

Offset 0x08000ba0 40

 On remarque le changement de l’adresse de List de 0x2000001c à 0x08000ba0 ceci car l’offset


n’est plus enregistré dans la RAM mais plutôt dans la ROM. L’espace mémoire dédié à l’offset
« =40octets » n’est plus réservé.

18. Quels sont les changements détectés dans le fichier main_const_list.txt ?

 Les changements remarqués dans le fichier main_const_list.txt est le fait d’avoir AREA ||.
constdata ||, au lieu d’avoir AREA || .data ||.

19. Copier les valeurs observées dans la question 16 dans la première ligne du tableau, puis
examiner de nouveau la section (Image component sizes) et remplir les valeurs dans la
deuxième ligne, quel sont les changements observés, donner une explication par rapport à ces
changements ?

Code Data RO data RW data ZI data debug

Non const offset 116 10 40 0 40 1479

 La valeur de debug est modifiée car le code est modifié.


La taille de RO data est passée de 0 à 40 (READ ONLY ROM) et la taille de RW data est passée
de 40 à 0 (READ WRITE RAM ) car l’offset est stocké dans la partie RO au lieu d’être stocké
dans la partie RW.