Faire le langage de programmation compilateurs d'abord traduire à l'assemblée ou directement en code machine?
Je suis principalement intéressé à populaires et largement utilisés compilateurs, comme gcc. Mais si les choses sont faites différemment avec différents compilateurs, j'aimerais savoir que, trop.
La prise de gcc comme un exemple, est-il compiler un programme écrit en C directement à machine code, ou faut-il d'abord la convertir lisible par l'homme de l'assemblée, et seulement ensuite utilise un (intégré?) assembleur pour traduire l'assemblée programme en binaire, machine code, une série d'instructions pour le PROCESSEUR?
Est l'aide de l'assemblée de code pour créer un exécutable binaire de manière significative une opération coûteuse? Ou est-il un moyen relativement simple et rapide chose à faire?
(Supposons que nous avons affaire avec seulement la famille x86 de processeurs, et tous les programmes sont écrits pour Linux.)
Je serais très reconnaissant pour toute l'aide et de la pensée sur la matière. Merci!!!!
Vous devez vous connecter pour publier un commentaire.
gcc produit en fait de l'assembleur et assemble à l'aide de la comme assembleur. Pas tous les compilateurs ne ce - MS compilateurs produire le code de l'objet directement, si vous pouvez faire générer assembleur de sortie. La traduction assembleur de code objet est un processus assez simple, au moins par rapport à la compilation.
Certains compilateurs produire d'autres langage de haut-niveau du code que de leur sortie, par exemple, cfront, le premier compilateur C++ produit C comme sa sortie qui a ensuite été compilé par un compilateur C.
Noter que ni directe de la compilation ou de l'assemblée en fait de produire un exécutable. Ce qui est fait par le de l'éditeur de liens, qui présente les différents objets des fichiers de code produit par la compilation/assemblée, décide de tous les noms qu'ils contiennent et le produit final binaire exécutable.
Presque tous les compilateurs, y compris la gcc, à produire assemblée de code parce que c'est plus facile---à la fois à produire et à déboguer le compilateur. Les principales exceptions sont généralement juste-à-temps des compilateurs ou interactif, compilateurs, dont les auteurs ne veulent pas la performance de frais généraux ou les tracas de bifurquer un ensemble de processus à exécuter l'assembleur. Quelques exemples intéressants comprennent
Standard ML de New Jersey, qui s'exécute de manière interactive et compile chaque expression à la volée.
La tinycc compilateur, qui est conçu pour être assez rapide pour compiler, de charger et d'exécuter un script C en moins de 100 millisecondes, et, par conséquent, ne veut pas la surcharge de l'appel de l'assembleur et l'éditeur de liens.
Ce que ces cas ont en commun une volonté de "instantané" de la réponse. Les monteurs et les linkers sont beaucoup rapide, mais pas assez bonnes pour interactif de réponse. Encore.
Il y a aussi une grande famille de langues, comme Smalltalk, Java, et Lua, qui compile en bytecode, pas de code assembleur, mais dont les mises en œuvre peuvent, plus tard, de le traduire directement du bytecode en code machine sans le bénéfice d'un assembleur.
(Note de bas de page: dans le début des années 1990, Marie Fernandez et j'ai écrit la New Jersey Code Machine, Trousse À Outils, pour qui la code est en ligne, ce qui génère du C les bibliothèques que les rédacteurs du compilateur à utiliser afin de contourner la norme de l'assembleur et l'éditeur de liens. Marie l'a utilisé à peu près le double de la vitesse de son optimisation de l'éditeur de liens lors de la génération de
a.out
. Si vous n'écrivez pas sur le disque, les accélérations sont encore plus...)Les compilateurs, en général, d'analyser le code source dans un Arbre de Syntaxe Abstraite (un AST), puis par l'intermédiaire de la langue. Alors seulement, habituellement après quelques optimisations, ils émettent de la langue cible.
Sur gcc, il permet de compiler une grande variété de cibles. Je ne sais pas si pour les architectures x86, il compile à l'assemblée, mais je n'ai vous donner une idée sur les compilateurs - et vous l'avez demandé que trop.
Selon chapitre 2 de Introduction à l'Ingénierie Inverse du Logiciel (par Mike Perry et Nasko Oskov), gcc et cl.exe (la fin du compilateur pour MSVC++) ont la -S interrupteur, vous pouvez utiliser à la sortie de l'assemblée que chaque compilateur produit.
Vous pouvez également exécuter gcc en mode verbose (
gcc -v
) pour obtenir une liste des commandes qu'il exécute pour voir ce qu'il fait derrière les coulisses.GCC compile à l'assembleur. Certains autres compilateurs ne pas. Par exemple, LLVM-GCC compile de LLVM-assemblage ou de LLVM bytecode, qui est ensuite compilé en code machine. Presque tous les compilateurs ont une sorte de représentation interne, LLVM-GCC utilisation LLVM, et, autant que je me souvienne, GCC utilise ce qu'on appelle GIMPLE.
Aucune des réponses clarifie le fait qu'un ASSEMBLEUR est la première couche d'abstraction entre le CODE BINAIRE et dépend de la MACHINE CODE SYMBOLIQUE. Un compilateur est la deuxième couche d'abstraction entre dépend de la MACHINE CODE SYMBOLIQUE et la MACHINE INDÉPENDANTE CODE SYMBOLIQUE.
Si un compilateur convertit directement le code en code binaire, par définition, il sera appelé assembleur et pas un compilateur.
Il est plus approprié de dire qu'un compilateur de CODE INTERMÉDIAIRE qui peut ou peut ne pas être en langage d'assemblage par exemple, Java utilise les octets de code comme le code intermédiaire et de byte code assembleur de la machine virtuelle java (JVM).
EDIT: vous pouvez Vous demander pourquoi un assembleur toujours produit dépend de la machine code et pourquoi un compilateur est capable de produire du code indépendant de la machine. La réponse est très simple. Un assembleur est en correspondance directe de code machine et, par conséquent, de l'assemblée de la langue qu'elle produit est toujours dépend de la machine. Au contraire, on peut écrire plus d'une des versions de compilateur pour différentes machines. Donc, pour exécuter notre code indépendamment de la machine, nous devons compiler le même code, mais sur le compilateur de la version écrite de cette machine.
Visual C++ a un commutateur à la sortie de l'assemblée du code, donc je pense qu'il génère le code d'assemblée avant de sortir du code machine.
Dans la plupart des multi-pass compilateurs langage d'assemblage est généré lors de la génération de code étapes. Cela permet d'écrire l'analyseur lexical, la syntaxe et la sémantique des phases une fois et ensuite générer du code exécutable à l'aide d'un simple assembleur de back-end. c'est beaucoup utilisé dans les compilateurs croisés telle compilateurs C qui génère pour une gamme de différents cpu.
Juste au sujet de chaque compilateur a une forme de ce que son implicitement ou explicitement étape.
Il y a beaucoup de phases de compilation. En résumé, il y a le front-end qui lit le code source, il se décompose en jetons, et enfin dans un arbre d'analyse.
L'extrémité arrière est responsable de la première génération d'un code séquentiel comme trois de code d'adresse par exemple:
code:
dans:
Puis l'optimisation de ce dernier, de le traduire dans l'assemblée et enfin en langage machine. Toutes les étapes sont disposés en couches avec soin de sorte que lorsque cela est nécessaire, l'un d'eux peut être remplacé
Vous serez probablement intéressé à l'écoute de ce pod cast: Fonctionnement interne de GCC
Compilateurs Java compiler en java byte code (format binaire) et ensuite exécuter ce à l'aide d'une machine virtuelle (jvm).
Tandis que ceci peut sembler lent, il - elle peut être plus rapide parce que la JVM peut tirer parti plus tard instructions du PROCESSEUR et de nouvelles optimisations. Un compilateur C++ de ne pas le faire - vous avez pour objectif le jeu d'instruction au moment de la compilation.
Bien que tous les compilateurs ne pas convertir le code source dans un niveau intermédiaire de code, mais il y a un pont de prendre le code source de la machine au niveau du code en plusieurs compilateurs