Je sais que c'est une question très basique, mais lorsque je compile mon code C / C ++ avec GCC / G ++, quel est le type de sortie intermédiaire avant que l'assembleur n'entreille en jeu pour générer le code de la machine? Est-ce quelque chose comme x86 instructions? P>
6 Réponses :
Ce doit être le code de montage. Vous pouvez l'obtenir en utilisant -s code> indicateur de commande de commande pour la compilation. P>
Il n'y a pas de "sortie intermédiaire". La première sortie que vous obtenez est le code de la machine. (Bien que vous puissiez obtenir une sortie intermédiaire C / C ++ en appelant seul em> le pré-processeur avec -e code>.) P>
La chaîne de traitement de GCC est la suivante: p>
Votre code source p> li>
code source prétraité (développer les macros et inclut, bandes commentaires) ( compile à assembler ( Assemblez au binaire ( lien vers exécutable p> li>
ul>
à chaque étape, j'ai répertorié les drapeaux compilateurs concernés qui rendent le processus s'arrêter là-bas, ainsi que le suffixe de fichier correspondant. P>
Si vous compilez avec La phase "Compilation" appropriée est la partie de levage réelle. Le préprocesseur est essentiellement un outil distinct et indépendant (bien que son comportement soit mandaté par les normes C et C ++), ainsi que l'assembleur et la lieur sont des outils autonomes distincts et distincts qui viennent d'implémenter, respectivement, le format d'instruction binaire du matériel et la Format exécutable chargé du système d'exploitation. P> -e code>,
.ii code>) p> l>
-s code>,
.s code>) p> li>
-c code>,
.o code>) p> li>
-flto code>, les fichiers d'objet seront ornés avec Gimple Bytecode, qui est un type de format intermédiaire de bas niveau, dont le but est de retarder la compilation finale réelle à la phase de liaison, qui permet des optimisations de temps de liaison. p>
+1, excellente réponse. Vous voudrez peut-être ajouter un blurb sur ce que l'assemblage est, car il semble que l'astucieux ne soit pas clairement clair à ce sujet.
@ CHA0SITE: Merci ... Voyons; L'OP est la bienvenue à demander des éclaircissements, auquel cas je serai heureux de se développer.
@Kerreksb merci beaucoup pour la réponse détaillée, je pense que je l'obtiens maintenant. La réponse de Zarakikenpachi ci-dessous était également très utile. Je suppose donc que GCC reçoit des informations sur mon matériel avant de générer l'assemblage ou un compilateur séparé pour chaque type de matériel?
@Cemre: GCC est divisé en interne en une langue frontale (par exemple C, C ++, Fortran) et une version matérielle (x86, PPC, bras, etc.), mais tout cela est compilé dans un compilateur fixe binaire. Vous devez construire la suite compilatrice entière de l'architecture cible souhaitée, et le programme binaire résultant pour votre code source est donc déterminé par le compilateur réel que vous choisissez. Vous avez besoin d'un compilateur à bras pour les binaires à bras, un compilateur X86 pour les fichiers binaires X86, etc. Compilation d'une plate-forme qui ne s'appelle pas la vôtre s'appelle "Compilation croisée".
@Cemre: Ce que GCC fait (en interne) transforme le code en une représentation interne agnostique angnostique linguistique appelée arborescence de syntaxe abstraite par ce qu'on appelle un front-end, dont il y en a un pour chaque langue. Cette AST est ensuite transmise à un back-end spécifique à la machine qui génère un assemblage. Cependant, comme Kerrek a dit, vous ne pouvez pas construire que le front-end ou simplement le back-end, vous ne pouvez utiliser que tout le compilateur (c'est à la manière dont GCC a été conçu, ce n'est pas une restriction absolue).
@ CHA0SITE: Pour nommer un exemple, CLANG est la langue familiale C-Family Frontend, qui fait le premier prétraitement / compilation (une représentation intermédiaire appelée LLVM IR), puis les mains générées sur la LLVM qui génère l'assemblage et la main À la liaison système (principalement LD / Gold sur * Nix Systems, link.exe sous Windows, bien qu'il existe un projet LLVM Linker se déroulant).
Donc, la compilation de l'exécutable dans GCC se compose de 4 parties: p>
1.) Prétraitement (GCC -E Main.c> Main.i; Transforme * .c à * .i) Inclure l'expansion, les processus marcos. Supprime les commentaires. P>
2.) Compilation (GCC -S -S -S MAINT.I; Transforme * .Je à * .s, s'il réussit) Compile C-Code à assembleur (sur la cible X86 Architecture Il s'agit de x86-assemblage, sur la cible X86_64 Architecture, il s'agit d'un ensemble X64, sur une architecture de bras cible, il s'agit d'un assemblage de bras, etc.) La plupart des avertissements et des erreurs se produisent au cours de cette partie (par exemple, une déclaration d'erreur et d'alerte) p>
3.) Assemblée (comme Main.S -o Main.o; Transforme * .Je à * .o, encore une fois au succès) Assemblages générés par l'assembleur au code de la machine. Bien qu'il existe toujours une adresse relative des procédures, etc. p>
4.) Liaison (GCC Main.O) Remplace les adresses relatives avec des adresses absolues. Supprime du texte inutile. Relier des erreurs et des avertissements au cours de cette phase. Et à la fin (en cas de succès), nous obtenons un fichier exécutable. P>
Donc, pour répondre à votre question, la sortie intermédiaire que vous voulez dire est en réalité contenue de la langue d'assemblage - voir wiki à propos de celui-ci Langue de montage Wiki . P>
Merci beaucoup pour la réponse détaillée. C'était très utile.
chaîne d'outils GCC, compile le programme du code source vers le bas du code de la machine. Le compilateur génère le code de montage que l'assembleur s'assemble dans le code de la machine. ici est un bon tutoriel pour les débutants. P>
Voici une représentation graphique des étapes de compilation de la GCC par courtoisie de Magazine RedHAT A>: p>
Contrairement à quelles autres réponses impliquent, il n'y a pas d'étape de montage - plutôt, générer un code d'assembleur remplace la génération de code d'objet; Il n'a pas grand sens de convertir une représentation en mémoire à un textuel si ce que vous voulez vraiment est une représentation binaire. P> P>
Eh bien, oui, il n'a pas grand sens de générer des mnémoniques, destinés à être lu à lire, si vous allez faire du code d'objet de toute façon. Mais les mnémoniques sont presque 1: 1 avec le code d'objet et la partie génération de code de l'assembleur est i> fait (calculer les adresses de saut, ce type de chose).
Sortie I> Intermédiaire i> voulez-vous dire?
g ++ code> génère directement l'assemblage.
Les options suivantes peuvent être utiles:
-g -wa, -ahl = main.s code>. Ils provoquent GCC / G ++ d'émettre l'assemblage avec un code source de haut niveau entrelacé.
Ce n'est pas du tout une question fondamentale.