Ce tp va nous permettre de voir dans un premier temps comment sont codés en langage d’assemblage x86, le test si-alors-sinon, et les itérations while et for. Dans un second temps, on verra qu’il est possible de modifier l’emplacement mémoire d’une variable très utilisée afin d’optimiser le programme. Nous verrons dans un tp ultérieur que cela permet d’avoir des programmes plus rapides.
1h30
Quand un programme utilise une boucle, il y a toujours comparaison d'une variable avec une valeur cible. Cette comparaison permet alors d'arrêter la boucle. De plus si un programmeur décide de mettre à l'intérieur d'une boucle une instruction qui ne sert à rien (et oui il y en a...), un compilateur optimisant va enlever cette instruction.
Dans les 3 programmes suivants, noter l'emplacement mémoire des variables.
Compiler ces 3 programmes à l’aide de la commande :
$gcc -Wall programme.c -o programme
Les lancer et voir ce qu'ils font (pas grand chose). Traduire ces programmes en langage d'assemblage à l'aide de la commande :
$gcc -Wall -S programme.c
Visualiser ces nouveaux fichiers sources assembleur et les
analyser pour comprendre le codage du test if-else
et des itérations while et for.
Remplacer le mot-clé int
par
unsigned int
. Quels sont les changements dans les codes
assembleur produits ?
Segmenter le code assembleur obtenu en blocs correspondant aux instructions du langage C.
Optimiser ces programmes à l'aide de la commande :
$gcc -Wall -O -S programme.c
Segmenter le code assembleur obtenu en blocs correspondant
aux instructions du langage C. Retrouve-t'on les mêmes motifs ?
La segmentation est-elle complète ?
Que sont devenues nos variables ?
Reprendre les trois programmes précédents, les
copier en les renommant : programme_reg.c.
Ajouter dans ces 3 programmes le mot clef
register
en préfixant les déclarations des
variables.
Traduire en langage d’assemblage ces 3 programmes en faisant
attention à avoir toujours _reg
dans les noms des différents
fichiers, de façon à pouvoir comparer les différents
codes assembleurs. Ne pas activer l'optimisation !
Visualiser les 3 fichiers .s produits et
noter l'emplacement mémoire des variables.
Conclure quant à la vitesse d’exécution attendue
de ces nouveaux programmes par rapport aux anciens.
Traduire en langage d’assemblage ces 3 programmes en faisant
attention à avoir toujours _regopt
dans les noms des différents
fichiers. Activer l'optimisation !
Visualiser les 3 fichiers .s produits et
noter l'emplacement mémoire des variables.
Conclure sur l'efficacité relative du mot-clé
register
et de l'optimisation par gcc.
Nous avons vu dans les deux parties précédentes que gcc
optimisait bien le code du programme... mais que l'on pouvait lui donner des
conseils.
Nous allons voir que l'on peut aussi lui donner des ordres.
Modifier les programmes ci-dessus en déplaçant
les variables locales en tête des fichiers. Elle deviennent donc
globales.
Observer que les variables ne sont plus situées sur
la pile.
Tester les optimisations ci-dessus et conclure.
Modifier les programmes en remplaçant les déclarations par :
Attention : ce code n'obeït plus à la norme ANSI ! Il n'est donc plus portable...
Tester différentes compilations.
Comparer les résultats obtenus.
Tester différents registres.
Conclure sur ce TP.