Réponses:
=====> COMPILATION PROCESS <======
|
|----> Input is Source file(.c)
|
V
+=================+
| |
| C Preprocessor |
| |
+=================+
|
| ---> Pure C file ( comd:cc -E <file.name> )
|
V
+=================+
| |
| Lexical Analyzer|
| |
+-----------------+
| |
| Syntax Analyzer |
| |
+-----------------+
| |
| Semantic Analyze|
| |
+-----------------+
| |
| Pre Optimization|
| |
+-----------------+
| |
| Code generation |
| |
+-----------------+
| |
| Post Optimize |
| |
+=================+
|
|---> Assembly code (comd: cc -S <file.name> )
|
V
+=================+
| |
| Assembler |
| |
+=================+
|
|---> Object file (.obj) (comd: cc -c <file.name>)
|
V
+=================+
| Linker |
| and |
| loader |
+=================+
|
|---> Executable (.Exe/a.out) (com:cc <file.name> )
|
V
Executable file(a.out)
Le prétraitement C est la première étape de la compilation. Il gère:
#define
déclarations.#include
déclarations.Le but de l'unité est de convertir le fichier source C en fichier de code Pure C.
Il y a six étapes dans l'unité:
Il combine des caractères dans le fichier source, pour former un "TOKEN". Un jeton est un ensemble de caractères sans «espace», «tabulation» et «nouvelle ligne». Par conséquent, cette unité de compilation est également appelée "TOKENIZER". Il supprime également les commentaires, génère des entrées de table de symboles et de table de déplacement.
Cet appareil vérifie la syntaxe du code. Par exemple:
{
int a;
int b;
int c;
int d;
d = a + b - c * ;
}
Le code ci-dessus générera l'erreur d'analyse car l'équation n'est pas équilibrée. Cette unité vérifie cela en interne en générant l'arborescence de l'analyseur comme suit:
=
/ \
d -
/ \
+ *
/ \ / \
a b c ?
Par conséquent, cet appareil est également appelé PARSER.
Cette unité vérifie la signification des déclarations. Par exemple:
{
int i;
int *p;
p = i;
-----
-----
-----
}
Le code ci-dessus génère l'erreur "Affectation d'un type incompatible".
Cette unité est indépendante de la CPU, c'est-à-dire qu'il existe deux types d'optimisation
Cette unité optimise le code sous les formes suivantes:
Par exemple:
{
int a = 10;
if ( a > 5 ) {
/*
...
*/
} else {
/*
...
*/
}
}
Ici, le compilateur connaît la valeur de «a» au moment de la compilation, donc il sait également que la condition if est toujours vraie. Par conséquent, il élimine la partie autre du code.
Par exemple:
{
int a, b, c;
int x, y;
/*
...
*/
x = a + b;
y = a + b + c;
/*
...
*/
}
peut être optimisé comme suit:
{
int a, b, c;
int x, y;
/*
...
*/
x = a + b;
y = x + c; // a + b is replaced by x
/*
...
*/
}
Par exemple:
{
int a;
for (i = 0; i < 1000; i++ ) {
/*
...
*/
a = 10;
/*
...
*/
}
}
Dans le code ci-dessus, si 'a' est local et n'est pas utilisé dans la boucle, il peut être optimisé comme suit:
{
int a;
a = 10;
for (i = 0; i < 1000; i++ ) {
/*
...
*/
}
}
Ici, le compilateur génère le code d'assemblage afin que les variables les plus fréquemment utilisées soient stockées dans les registres.
Ici, l'optimisation dépend du processeur. Supposons que s'il y a plus d'un saut dans le code, ils sont convertis en un comme:
-----
jmp:<addr1>
<addr1> jmp:<addr2>
-----
-----
Le contrôle passe directement au.
Ensuite, la dernière phase est la liaison (qui crée un exécutable ou une bibliothèque). Lorsque l'exécutable est exécuté, les bibliothèques dont il a besoin sont chargées.
Représentation ASCII:
[Source Code] ---> Compiler ---> [Object code] --*
|
[Source Code] ---> Compiler ---> [Object code] --*--> Linker --> [Executable] ---> Loader
| |
[Source Code] ---> Compiler ---> [Object code] --* |
| |
[Library file]--* V
[Running Executable in Memory]
J'espère que cela vous aidera un peu plus.
Tout d'abord, parcourez ce diagramme:
(img source->internet)
Vous créez un morceau de code et enregistrez le fichier (code source), puis
Prétraitement : - Comme son nom l'indique, il ne fait pas partie de la compilation. Ils demandent au compilateur d'effectuer le prétraitement requis avant la compilation proprement dite. Vous pouvez appeler cette phase Substitution de texte ou interpréter des directives spéciales de préprocesseur désignées par #.
Compilation : - La compilation est un processus dans lequel un programme écrit dans une langue est traduit dans une autre langue ciblée. S'il y a des erreurs, le compilateur les détecte et les signale.
Assembler : - Le code d'assemblage est traduit en code machine. Vous pouvez appeler l'assembleur un type spécial de complicateur.
Liaison : - Si ces morceaux de code nécessitent un autre fichier source à lier, liez-les pour en faire un fichier exécutable.
Il y a de nombreux processus qui se produisent après cela. Oui, vous l'avez deviné, voici le rôle du chargeur:
Loader : - Il charge le code exécutable en mémoire; le programme et la pile de données sont créés, le registre est initialisé.
Petite info supplémentaire: - http://www.geeksforgeeks.org/memory-layout-of-c-program/ , vous pouvez voir la disposition de la mémoire là-bas.
Compilateur: C'est un programme qui traduit un programme de langage de haut niveau en un programme de langage machine. Un compilateur est plus intelligent qu'un assembleur. Il vérifie toutes sortes de limites, plages, erreurs, etc. Mais son temps d'exécution du programme est plus important et occupe une plus grande partie de la mémoire. Il a une vitesse lente. Parce qu'un compilateur parcourt tout le programme et traduit ensuite l'ensemble du programme en codes machine. Si un compilateur s'exécute sur un ordinateur et produit les codes machine pour le même ordinateur, il est alors appelé auto-compilateur ou compilateur résident. D'un autre côté, si un compilateur s'exécute sur un ordinateur et produit les codes machine pour un autre ordinateur, il est alors appelé compilateur croisé.
Éditeur de liens: dans les langages de haut niveau, certains fichiers d'en-tête ou bibliothèques intégrés sont stockés. Ces bibliothèques sont prédéfinies et contiennent des fonctions de base essentielles à l'exécution du programme. Ces fonctions sont liées aux bibliothèques par un programme appelé Linker. Si l'éditeur de liens ne trouve pas de bibliothèque d'une fonction, il en informe le compilateur, puis le compilateur génère une erreur. Le compilateur invoque automatiquement l'éditeur de liens comme dernière étape de la compilation d'un programme. Non intégré aux bibliothèques, il relie également les fonctions définies par l'utilisateur aux bibliothèques définies par l'utilisateur. Habituellement, un programme plus long est divisé en sous-programmes plus petits appelés modules. Et ces modules doivent être combinés pour exécuter le programme. Le processus de combinaison des modules est effectué par l'éditeur de liens.
Loader: Loader est un programme qui charge les codes machine d'un programme dans la mémoire système. En informatique, un chargeur est la partie d'un système d'exploitation qui est responsable du chargement des programmes. C'est l'une des étapes essentielles du processus de démarrage d'un programme. Parce qu'il place les programmes en mémoire et les prépare à l'exécution. Le chargement d'un programme implique la lecture du contenu du fichier exécutable en mémoire. Une fois le chargement terminé, le système d'exploitation démarre le programme en passant le contrôle au code du programme chargé. Tous les systèmes d'exploitation prenant en charge le chargement de programmes ont des chargeurs. Dans de nombreux systèmes d'exploitation, le chargeur réside en permanence en mémoire.
Wikipédia devrait avoir une bonne réponse, voici mes pensées:
*
*
Linkers and Loaders de LinuxJournal explique ce concept avec clarté. Il explique également comment le nom classique a.out est venu. (sortie assembleur)
Un bref résumé,
c program --> [compiler] --> objectFile --> [linker] --> executable file (say, a.out)
nous avons l'exécutable, donnez maintenant ce fichier à votre ami ou à votre client qui a besoin de ce logiciel :)
quand ils exécutent ce logiciel, disons en le tapant dans la ligne de commande ./a.out
execute in command line ./a.out --> [Loader] --> [execve] --> program is loaded in memory
Une fois le programme chargé dans la mémoire, le contrôle est transféré à ce programme en faisant pointer le PC (compteur de programme) sur la première instruction de a.out
Il lira le fichier source qui peut être de type .c ou .cpp etc. et le traduira en fichier .o appelé fichier objet.
Il combine les différents fichiers .o qui peuvent être générés pour plusieurs fichiers sources dans un fichier exécutable (format ELF dans GCC). Il existe deux types de liens:
Un programme qui charge le fichier exécutable dans la mémoire principale de la machine.
Pour une étude détaillée de ces trois étapes de l'exécution du programme sous Linux, veuillez lire ceci .
Les modifications du compilateur vérifient les erreurs de votre code source et le transforment en code objet. C'est le code exécuté par le système d'exploitation.
Souvent, vous n'écrivez pas un programme entier dans un seul fichier, alors l'éditeur de liens relie tous vos fichiers de code objet.
votre programme ne sera exécuté que s'il est en mémoire principale
Linker & Interpreter sont des interpréteurs mutuellement exclusifs qui obtiennent du code ligne par ligne et s'exécutent ligne par ligne.
Compilateur Il convertit le code source en code objet.
Éditeur de liens Il combine les fichiers objets multiples en un seul fichier programme exécutable.
Loader Il charge le fichier exécutable dans la mémoire principale.
Un compilateur est un programme spécial qui traite les instructions écrites dans un langage de programmation particulier et les transforme en langage machine ou "code" utilisé par le processeur d'un ordinateur
Un compilateur traduit des lignes de code du langage de programmation en langage machine.
Un Linker crée un lien entre deux programmes.
Un chargeur charge le programme en mémoire dans la base de données principale, le programme, etc.
Compilateur: c'est un logiciel système qui corrige l'erreur des programmes, fichier objet, messages, etc.
Linker: c'est un logiciel système qui combine un ou plusieurs fichiers objets et éventuellement du code de bibliothèque dans une bibliothèque exicuable ou une liste d'erreurs
Loader: un programme qui charge le fichier exécutable dans la mémoire principale de la machine