Précédent Remonter Suivant

2  Compilation en plusieurs phases

C est un langage compilé. Cela signifie qu'un programme C est décrit par un fichier texte appelé fichier source. Ce fichier n'est pas exécutable par le microprocesseur, il faut le traduire en langage machine. Cette opération est effectuée par un programme appelé compilateur.

La compilation d'un programme C se décompose en 4 phases successives :
  1. Le traitement par le préprocesseur : le fichier source est analysé par un programme appelé préprocesseur qui effectue des transformations purement textuelles (remplacement de chaînes de caractères, inclusion d'autres fichiers source, etc.).
  2. La compilation : au cours de cette étape, le fichier engendré par le préprocesseur est traduit en assembleur, c'est à dire en une suite d'instructions qui sont chacunes associées à une fonctionnalité du microprocesseur (faire une addition, une comparaison, etc.).
  3. L'assemblage : cette opération transforme le code assembleur en un fichier binaire, c'est-à-dire en instructions directement compréhensibles par le processeur. Le fichier produit par l'assemblage est appelé fichier objet .o).
  4. L'édition de liens : un programme est souvent séparé en plusieurs fichiers source (ceci permet d'utiliser des librairies de fonctions standard déjà écrites comme les fonctions d'affichage par exemple). Une fois le code source assemblé, il faut donc lier entre eux les différents fichiers objets. L'édition de liens produit alors un fichier exécutable.
La commande gcc invoque tour à tour ces différentes phases. Des options de gcc permettent de stopper le processus de compilation après chaque des phases.

Nous allons illustrer cela sur le programme suivant (phases.c) :
/* ------------------------------
   Mon premier programme 
   ------------------------------------------------------------ */

#include <stdio.h>
#include <stdlib.h>

#define MAX     12

int foo = 3;
const int bar = 5;

extern int gee;

int 
main() 
{
    int bzu;             /* declaration et definition de bzu */ 

    bzu = MAX;           
    printf("Hello : %d\n", foo + bar + gee + bzu); 

    exit(EXIT_SUCCESS);
}

Préprocessing



Exercice 3
   Vérifiez dans la page de manuel de gcc le sens de l'option -E.


Exercice 4
   Produisez le résultat du prétraitement par le préprocesseur sur le programme phases.c dans un fichier phases.i.

Reportez vous éventuellement au TP précédent pour vous remémorer l'utilisation des redirections des entrées/sorties des commandes.


Exercice 5
   Comparez le contenu des fichiers phases.c et phases.i. En particulier
  1. Combien de lignes comporte chacun des fichiers phases.c et phases.i ?
  2. Qu'est devenu la ligne
    
    #include <stdio.h>
    
  3. Que sont devenus les commentaires ?
  4. Quel traitement a été réalisé sur la ligne
    
        bzu = MAX;
    
    Vous pouvez vérifiez cela en invoquant la commande « Macro expand region Â» (C-c C-e) du menu C d'emacs sur cette ligne.

Génération de code assembleur



Exercice 6
   Vérifiez dans la page de manuel de gcc le sens de l'option -S et produisez le code assembleur correspondant à phases.c.


Exercice 7
   Dans ce code assembleur, identifiez les différentes sections .data, .rodata, et .text.
  1. Quels symboles sont associés à la section .data ? À quoi correspond cette section ?

    Vérifiez en ajoutant une déclaration au programme phases.c
    .

  2. Quels symboles et valeurs sont associés à la section .rodata ? À quoi correspond cette section ?

    Vérifiez en modifiant phases.c
    pour ajouter un élément à cette section.

  3. Quel est le point d'entrée de ce programme ?
Référez vous éventuellement à vos manipulations de l'assembleur gas vu dans l'UE « Architecture élémentaire des ordinateurs (info 202) Â».

Génération du fichier objet



Exercice 8
   Trouvez comment indiquer à gcc de générer le fichier objet phases.o à partir de phases.c.


Exercice 9
   Comparer les résultats de la commande nm sur ce fichier .o avec ce que vous aviez identifié comme section dans le code assembleur.


Exercice 10
  
  1. Qu'indique nm pour les symboles printf, exit, et gee ?
  2. Où ces symboles sont-ils définis ? Quel programme est en charge de rechercher ces symboles ?
  3. Qu'est ce qui change dans le résultat de nm si on supprime l'utilisation de gee dans l'instruction printf du fichier phases.c ?


Exercice 11
   Comment expliquez vous le résultat de la commande strings sur ce fichier .o ?

En conclusion

Ces manipulations vous ont permis d'aborder le processus de compilation d'un programme C.

Ces manipulations sont représentatives de l'activité d'un programmeur : Soyez à l'aise et efficaces avec vos outils !

Concernant les différentes phases de compilation :
Précédent Remonter Suivant