Beachten Sie aus der obigen Ausgabe der vorverarbeiteten Datei, dass unser Programm das stdio angefordert hat.h-Header in unsere Quelle aufgenommen werden, die wiederum eine ganze Reihe anderer Header-Dateien angefordert hat.
Kompilierung
Der nächste Schritt besteht darin, die vorverarbeitete Datei als Eingabe zu verwenden, sie zu kompilieren und eine kompilierte Zwischenausgabe zu erzeugen. Die Ausgabedatei für diese Stufe erzeugt Assemblercode, der maschinenabhängig ist.
Durch die Verwendung des Flags „-S“ mit gcc können wir den vorverarbeiteten C-Quellcode in Assemblersprache konvertieren, ohne eine Objektdatei zu erstellen:
$ gcc -S HelloWorld.i -o HelloWorld.s
Obwohl ich mich nicht sehr mit der Programmierung auf Assemblerebene beschäftige, kommt ein kurzer Blick zu dem Schluss, dass diese Ausgabe auf Assemblerebene in irgendeiner Form von Anweisungen besteht, die der Assembler verstehen und in eine Sprache auf Maschinenebene konvertieren kann.
Assembly
Wie wir alle wissen ,können Maschinen nur binäre Sprache verstehen, so dass wir jetzt einen ASSEMBLER benötigen, der Assemblercode in „HelloWorld“ konvertiert.c“-Datei in Binärcode.
ASSEMBLER war eines der ersten Softwaretools, das nach der Erfindung des Digitalcomputers entwickelt wurde.
Wenn im Assemblercode Aufrufe externer Funktionen vorhanden sind, lässt der Assembler die Adressen der externen Funktionen undefiniert, die später vom Linker ausgefüllt werden.
Der Assembler kann wie unten gezeigt aufgerufen werden. Durch die Verwendung des Flags „-c“ in gcc können wir den Assemblercode in Code auf Maschinenebene konvertieren:
$ gcc -c HelloWorld.c -o HelloWorld.o
Das einzige, was wir erklären können, indem wir uns die HelloWorld ansehen.in der Datei geht es um die Zeichenfolge ELF in der ersten Zeile. ELF steht für executable and linkable format.
Eine Objektdatei und eine ausführbare Datei gibt es in verschiedenen Formaten wie ELF (Executable and Linking Format) und COFF (Common Object-File Format). Beispielsweise wird ELF auf Linux-Systemen verwendet, während COFF auf Windows-Systemen verwendet wird.
Dies ist ein relativ neues Format für Objektdateien und ausführbare Dateien auf Maschinenebene, die von gcc erstellt werden. Zuvor wurde ein Format namens .out verwendet. ELF soll ein ausgefeilteres Format sein als ein.out (Wir könnten in einem anderen zukünftigen Artikel tiefer in das ELF-Format eintauchen).
Wenn Sie Ihren Code kompilieren, ohne den Namen der Ausgabedatei anzugeben, hat die erzeugte Ausgabedatei den Namen ‚a.out‘, aber das Format wurde jetzt in ELF geändert. Es ist nur so, dass der Standardname der ausführbaren Datei gleich bleibt.
Verknüpfen
Dies ist die letzte Phase, in der alle Verknüpfungen von Funktionsaufrufen mit ihren Definitionen durchgeführt werden. Der Linker weiß, wo all diese Funktionen implementiert sind (der Assembler hat die Adresse aller aufzurufenden externen Funktionen belassen). Bis zu diesem Zeitpunkt weiß GCC nichts über die Funktion wie printf() .Der Assembler hätte die Adresse der aufzurufenden Funktionen belassen, und der Linker führt den letzten Vorgang durch, bei dem diese Adressen mit den tatsächlichen Definitionen gefüllt werden. Der Linker erledigt auch einige zusätzliche Aufgaben für uns. Es kombiniert unser Programm mit einigen Standardroutinen, die benötigt werden, um unser Programm auszuführen. Die endgültige ausführbare Größe ist also viel größer als die Eingabedatei!
Der gesamte Verknüpfungsprozess wird von gcc abgewickelt und wie folgt aufgerufen:
$ gcc -o Output HelloWorld.c
Der obige Befehl führt die Datei „HelloWorld.c“ und erzeugt die endgültige ausführbare Datei „Output“.
Wie Sie sehen können, ist die Ausgabedatei standardmäßig eine ausführbare Datei mit den Berechtigungen -rwxrwxr-x , was nur bedeutet, dass sie ausführbar ist Berechtigung für alle Benutzer (Eigentümer, Gruppe und andere). Wenn Sie diese ausführbare Datei ausführen, indem Sie einfach ‚./Output‘ Sie erhalten die endgültige Ausgabe unseres Programms!
Jetzt wissen wir also, wie ein C-Programm in eine ausführbare Datei konvertiert wird . Wir werden in den kommenden Artikeln etwas tiefer in die C-Programmierung eintauchen. Bis dahin viel Spaß beim Lernen! 🙂