GCC-Assembly-Ausgabe eines leeren Programms auf x86, win32

Lesezeit: 3 Minuten

Benutzeravatar von George
George

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 sein
  • pushl_: Ein langer (32-Bit) Push, der EBP auf den Stack legt
  • movl: 32-Bit-Verschiebung. Pseudo-C: EBP = ESP;
  • andl: Logisches UND. Pseudo-C: ESP = -16 & ESPich 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 zu 0x20 (dh. 32) für Funktionen oder 0x00 (dh. 0) Andernfalls. StorageClass Wert von 2 bezieht sich auf die Konstante IMAGE_SYM_CLASS_EXTERNAL

    – Jeromy Adofo

    1. November 2021 um 10:25 Uhr

  • Sicherlich main ist nicht der eigentliche Prozesseintrittspunkt; etwas müsste die Befehlszeile in C umwandeln argc / argv als Argumente für main um es anzurufen, und es muss eine Rücksendeadresse geben, um das zu codieren exit(retval) wenn main zurückkehrt. Handelt es sich um einen Zugang zu GCC-generiertem Code aus einer generischen MSVC-CRT-Funktion oder so etwas? Oder aus einer DLL?

    – Peter Cordes

    28. Januar um 5:53 Uhr

1412200cookie-checkGCC-Assembly-Ausgabe eines leeren Programms auf x86, win32

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy