Ich schreibe leere Programme, um Stackoverflow-Coder zu ärgern, NICHT. Ich erforsche gerade die GNU-Toolchain.
Das Folgende könnte mir jetzt zu tief gehen, aber um die leere Programm-Saga fortzusetzen, habe ich begonnen, die Ausgabe des C-Compilers zu untersuchen, das Zeug, das GNU verbraucht.
gcc version 4.4.0 (TDM-1 mingw32)
test.c:
int main()
{
return 0;
}
gcc -S test.c
.file "test.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
call ___main
movl $0, %eax
leave
ret
Können Sie erklären, was hier passiert? Hier ist mein Versuch, es zu verstehen. Ich habe die verwendet as
Handbuch und mein minimales x86-ASM-Wissen:
.file "test.c"
ist die Direktive für den logischen Dateinamen..def
: nach den docs “Definieren von Debugging-Informationen für einen Symbolnamen beginnen”. Was ist ein Symbol (ein Funktionsname/eine Variable?) und welche Art von Debugging-Informationen?.scl
: Dokumente sagen “Speicherklasse kann kennzeichnen, ob ein Symbol statisch oder extern ist”. Ist das dasselbe statisch und extern Ich weiß von C? Und was ist diese „2“?.type
: speichert den Parameter “als Typattribut eines Symboltabelleneintrags”Ich habe keine Ahnung..endef
: Kein Problem..text
: Nun, das ist problematisch, es scheint etwas namens Abschnitt zu sein, und ich habe gelesen, dass es der Ort für Code ist, aber die Dokumentation hat mir nicht zu viel gesagt..globl
“macht das Symbol für ld sichtbar.”das Handbuch ist diesbezüglich ziemlich klar._main:
Dies könnte die Startadresse (?) für meine Hauptfunktion seinpushl_
: Ein langer (32-Bit) Push, der EBP auf den Stack legtmovl
: 32-Bit-Verschiebung. Pseudo-C:EBP = ESP;
andl
: Logisches UND. Pseudo-C:ESP = -16 & ESP
ich verstehe nicht wirklich, was das soll.call
: Schiebt die IP auf den Stack (damit die aufgerufene Prozedur ihren Weg zurück finden kann) und fährt dort fort__main
ist. (was ist __main?)movl
: Diese Null muss die Konstante sein, die ich am Ende meines Codes zurückgebe. Der MOV platziert diese Null in EAX.leave
: Stellt den Stack nach einer ENTER-Anweisung (?) wieder her. Wieso den?ret
: geht zurück zur Befehlsadresse, die auf dem Stack gespeichert ist
Danke für Ihre Hilfe!
Gute Frage. 🙂
– Johannes Schaub – litb
22. August 2009 um 21:39 Uhr
Klingt nach einer ausgezeichneten Übung für einen echten Geek.
– JesperE
22. August 2009 um 21:41 Uhr
Ich habe die COFF-Spezifikation gefunden. Dies sollte einige Hinweise darauf geben, was “32” in “.type” bedeutet usw.: microsoft.com/whdc/system/platform/firmware/PECOFFdwn.mspx
– Johannes Schaub – litb
22. August 2009 um 21:51 Uhr
könnte nützlich sein: stackoverflow.com/questions/823138/…
– Nate Kohl
22. August 2009 um 21:51 Uhr
@JohannesSchaub-litb Der Link zur PE/COFF-Spezifikation scheint derzeit nicht aktiv zu sein, aber ich habe ihn auch unter diesem Link gefunden docs.microsoft.com/en-us/windows/win32/debug/pe-format. Im Abschnitt mit dem Titel „COFF Symbol Table“ sehen wir „Type“ und „StorageClass“ als Offsets 14 bzw. 16. Diese werden in den Abschnitten mit dem Titel “Typdarstellung” bzw. “Speicherklasse” weiter detailliert. Zusammenfassend setzen Microsoft-Tools die
Type
Feld zu0x20
(dh.32
) für Funktionen oder0x00
(dh.0
) Andernfalls.StorageClass
Wert von2
bezieht sich auf die KonstanteIMAGE_SYM_CLASS_EXTERNAL
– Jeromy Adofo
1. November 2021 um 10:25 Uhr