Le but de ce tp est de vous montrer le principe d’une pile, sa gestion et de voir où se trouvent les
différentes données d’un programme.
En même temps, on va voir la taille mémoire occupée par différentes données
déclarées initialisées ou non.
Vous pourrez aussi remarquer le codage des nombres négatifs, et voir que le microprocesseur utilise le complément
à 2, comme nous l'avons vu lors d'un Td du premier semestre.
1h30
La pile est une zone mémoire dans laquelle il est possible de stocker des données temporaires. Dans les deux Tp précédents, vous avez dû remarquer dans les différents sources des programmes que les mêmes lignes de code se trouvaient toujours en début de code source :
En fin de source, on trouve également :
Vous allez voir dans ce TP, et surtout comprendre, à quoi servent ces lignes.
Attention : Le cadre de pile de la fonction main est toujours différent et plus complexe que celui des autres fonctions. Je vous propose donc de le laisser de côté et d'utiliser une fonction auxiliaire main2.
Saisir le programme suivant, écrit en langage C, que vous devez comprendre assez facilement.
Traduisez-le en langage d’assemblage en tapant la commande:
$gcc -Wall -S pile.c
Notez l'utilisation de -Wall qui demande au compilateur C de vous donner des avertissements supplémentaires.
Utilisation recommandée pour TOUTE compilation d'un code C
Visualiser le fichier source en langage d’assemblage. Attention le compilateur génère
cette année des directives .cfi* (Call Frame Information). Ces directives ne servent
que pour le débogage, et en particulier pour l'affichage de la pile en cas d'erreur. Vous pouvez donc les supprimer ou
les ignorer sans vergogne.
Segmenter le programme et Faire le dessin de la pile et de l'occupation mémoire.
Conclure sur la taille des différents types.
Changer l’ordre des déclarations de variables (par exemple mettre mh entre mb et mc)
de façon à ne pas les avoir déclarées en ordre de taille croissante.
Le traduire en langage d’assemblage.
Visualiser le fichier source en langage d’assemblage.
Faire le dessin de la pile et de l'occupation mémoire.
Conclure sur l'intelligence de GCC.
Desassembler le fichier objet :
$objdump -d pile.s > pile.dis
Constater le codage des nombres négatifs. (voir variable
Vous pouvez aussi jeter un oeil sur le codage des nombres flottantes (variable mk, ligne 20).
Remplacer les lignes int h
et int mh
respectivement par
static int h
et static int mh
.
Recommencer l’étude précédente et conclure.
Nous allons approfondir un peu notre connaissance sur la pile.
Pour cela je vous invite à saisir le programme suivant :
Ce programme contient trois fonctions, main, main2 et appel_fonction.
Sachant que le compilateur C lit votre programme de haut en bas (dans ce sens), expliquer l'erreur obtenue pendant la compilation.
Après traduction en langage d’assemblage, on récupère le source suivant :
Analyser le programme pile2.c de façon à comprendre pile2.s.
Donner le nombre de cadres de piles que le programme pile2.s contient,
Expliquer chaque ligne du source assembleur.
Dessiner la zone mémoire de ce programme.
Pourquoi le return de la fonction main n'est-il pas traduit en assembleur ? Que devriez vous écrire pour le faire ? Conclure...
Optimiser le programme pile2.s (option O3) en tapant la commande :
$gcc S -O3 pile2.c -o pile2.opt.s
Vous devez obtenir un source optimisé, et donc beaucoup plus simple, donc plus facile à analyser.
Attention, dans ce mode, le compilateur peut ne pas respecter tout à fait l'ordre du
programme C...
Expliquer chaque ligne du source assembleur.
Dessiner la zone mémoire de ce programme.