Die Verarbeitungskette von GCC ist wie folgt:
Ihr Quellcode
vorverarbeiteter Quellcode (Makros erweitern und Includes, Strip-Kommentare) ( -E
, .ii
)
wird zur Assembly kompiliert ( -S
, .s
)
assembliere zu binär ( -c
, .o
)
Link zur ausführbaren Datei
In jeder Phase habe ich die relevanten Compiler-Flags aufgelistet, die den Prozess dort anhalten lassen, sowie das entsprechende Dateisuffix.
Wenn Sie mit -flto
kompilieren, werden die Objektdateien mit GIMPLE bytecode verschönert, einer Art Low-Level-Zwischenformat, dessen Zweck es ist, die eigentliche Endkompilierung auf die Verknüpfungsstufe zu verzögern, was dies ermöglicht für Link-Time-Optimierungen.
Die "Kompilier" -Phase ist das eigentliche schwere Hebeteil. Der Präprozessor ist im Wesentlichen ein separates, unabhängiges Werkzeug (obwohl sein Verhalten von den C- und C ++ - Standards vorgeschrieben ist), und der Assembler und Linker sind tatsächlich separate, freistehende Werkzeuge, die im Grunde nur das binäre Befehlsformat der Hardware und die Betriebssystem ladbare ausführbare Format.
Die Kompilierung der ausführbaren Datei in GCC besteht also aus vier Teilen:
1.) Vorverarbeitung (gcc -E main.c & gt; main.i; transformiert * .c in * .i) Enthält Expansion, Prozesse Marcos. Entfernt Kommentare.
2.) Kompilieren (gcc -S main.i; transformiert * .i in * .s, falls erfolgreich) Kompiliert C-Code zu Assembler (auf der Ziel-x86-Architektur ist es x86-Assembly, auf der Ziel-x86_64-Architektur ist es x64-Assembly, auf der Zielarmarchitektur ist Arm-Assembly usw.) Die meisten Warnungen und Fehler treten während dieses Teils auf (z. B. Fehler- und Warnmeldungen).
3.) Assembly (wie main.s -o main.o; transformiert * .i in * .o, wieder wenn erfolgreich) Baugruppen generierten Assembler zum Maschinencode. Obwohl es immer noch relative Adresse von Verfahren und dergleichen gibt.
4.) Verknüpfen (gcc main.o) Ersetzt relative Adressen durch absolute Adressen. Entfernt nutzlosen Text. Verknüpfen von Fehlern und Warnungen während dieser Phase. Und am Ende (wenn erfolgreich), erhalten wir eine ausführbare Datei.
Also, um Ihre Frage zu beantworten, ist die Zwischenausgabe, die Sie meinen, tatsächlich so genannte Assemblersprache - siehe Wiki über das Assemblersprachen-Wiki .
Hier ist eine grafische Darstellung der GCC-Kompilierungsschritte mit freundlicher Genehmigung des Redhat-Magazins :
>
Im Gegensatz zu dem, was andere Antworten implizieren, gibt es keinen Assembly-Schritt - stattdessen erzeugt das Generieren von Assembler-Code die Generierung des Objekt-Codes; Es macht nicht viel Sinn, eine In-Memory-Repräsentation in eine Text-Repräsentation umzuwandeln, wenn das, was Sie wirklich wollen, eine binäre Repräsentation ist.
Es muss Assemblercode sein. Sie können es mithilfe von -S
flag in der Befehlszeile zum Kompilieren abrufen.
Es gibt keinen "Zwischenausgang". Die erste Ausgabe, die Sie erhalten, ist Maschinencode. (Sie können zwar eine C / C ++ - Zwischenausgabe erhalten, indem Sie only den Präprozessor mit -E
aufrufen.)