Verwenden Sie GCC, um eine lesbare Baugruppe zu erstellen?
Lesezeit: 10 Minuten
James
Ich habe mich gefragt, wie man es benutzt GCC in meiner C-Quelldatei, um eine mnemonische Version des Maschinencodes auszugeben, damit ich sehen konnte, in was mein Code kompiliert wurde. Sie können dies mit Java tun, aber ich konnte mit GCC keinen Weg finden.
Ich versuche, eine C-Methode in Assembly neu zu schreiben, und zu sehen, wie GCC dies tut, wäre eine große Hilfe.
Beachten Sie, dass „Bytecode“ normalerweise den Code bezeichnet, der von einer VM wie JVM oder der CLR von .NET verwendet wird. Die Ausgabe von GCC wird besser als “Maschinencode”, “Maschinensprache” oder “Assemblersprache” bezeichnet.
– Javier
17. August 2009 um 19:27 Uhr
Ich habe eine Antwort mit Godbolt hinzugefügt, da es ein sehr leistungsfähiges Tool ist, um schnell damit zu experimentieren, wie sich verschiedene Optionen auf Ihre Codegenerierung auswirken.
– Shafik Yaghmour
12. September 2014 um 2:35 Uhr
stackoverflow.com/a/19083877/995714
– phuklv
30. November 2014 um 6:33 Uhr
Weitere Tipps, wie Sie die Ausgabe von asm für Menschen lesbar machen, finden Sie unter: Wie entferne ich „Rauschen“ aus der Ausgabe der GCC/Clang-Assembly?
– Peter Cordes
5. September 2016 um 20:46 Uhr
Hier beantwortet: stackoverflow.com/questions/137038/… Verwenden Sie die Option -S für gcc (oder g++).
– wissen ist Macht
26. Juli 2017 um 19:38 Uhr
Bastien Leonard
Wenn Sie mit Debug-Symbolen (add -g zu Ihrer GCC-Befehlszeile, auch wenn Sie es auch verwenden -O31), können Sie verwenden objdump -S um eine besser lesbare Disassemblierung zu erzeugen, die mit C-Quelle verschachtelt ist.
>objdump --help
[...]
-S, --source Intermix source code with disassembly
-l, --line-numbers Include line numbers and filenames in output
objdump -drwC -Mintel ist schön:
-r zeigt Symbolnamen bei Umzügen (so würden Sie sehen puts in dem call Anleitung unten)
-R zeigt dynamische Verlinkungen / Symbolnamen (nützlich für gemeinsam genutzte Bibliotheken)
-C demangles C++ Symbolnamen
-w ist der “Wide”-Modus: Die Maschinencode-Bytes werden nicht umgebrochen
-Mintel: Verwenden Sie GAS/binutils MASM-ähnlich .intel_syntax noprefix Syntax statt AT&T
-S: Quellzeilen mit Disassemblierung verschachteln.
Sie könnten so etwas wie setzen alias disas="objdump -drwCS -Mintel" in deiner ~/.bashrc. Wenn nicht auf x86 oder wenn Sie die AT&T-Syntax mögen, lassen Sie es weg -Mintel.
Beachten Sie, dass dies ist nicht verwenden -r also die call rel32=-4 ist nicht mit kommentiert puts Symbolname. Und sieht aus wie kaputt call das springt in die Mitte des Aufrufbefehls in main. Denken Sie daran, dass die rel32 Die Verschiebung in der Aufrufcodierung ist nur ein Platzhalter, bis der Linker einen echten Offset ausfüllt (in diesem Fall zu einem PLT-Stub, es sei denn, Sie verknüpfen libc statisch).
Fußnote 1: Interleaving-Quelle kann unordentlich und in optimierten Builds nicht sehr hilfreich sein; dafür überlegen https://godbolt.org/ oder andere Möglichkeiten, um zu visualisieren, welche Anweisungen zu welchen Quellzeilen gehören. In optimiertem Code gibt es nicht immer eine einzelne Quellzeile, die eine Anweisung berücksichtigt, aber die Debug-Informationen wählen eine Quellzeile für jede asm-Anweisung aus.
Gibt es einen Schalter, um nur die Intel-Anweisungen abzurufen?
– James
17. August 2009 um 19:39 Uhr
All dies sind Intel-Anweisungen, da sie auf Intel-Prozessoren ausgeführt werden: D.
– ganz
18. August 2009 um 4:01 Uhr
@toto Ich denke, er meint Intel-Syntax anstelle von AT & T-Syntax
– Amok
9. Oktober 2009 um 21:56 Uhr
Auf die zwischengeschaltete Objektdatei kann mit der Schalterfolge verzichtet werden -Wa,-adhln -g to gcc. Dies setzt voraus, dass der Assembler Gas ist, und dies muss nicht immer der Fall sein.
Fügen Sie zusätzliche Kommentarinformationen in den generierten Assemblycode ein, um ihn besser lesbar zu machen.
[…] Zu den hinzugefügten Kommentaren gehören:
Informationen zur Compilerversion und Kommandozeilenoptionen,
die den Assembleranweisungen zugeordneten Quellcodezeilen in der Form FILENAME:LINENUMBER:CONTENT OF LINE,
Hinweise darauf, welche High-Level-Ausdrücke den verschiedenen Assemblerbefehlsoperanden entsprechen.
Aber dann würde ich alle Schalter verloren, für die ich gebraucht habe objdump – objdump -drwCS -Mintelalso wie kann ich so etwas verwenden verbose mit objdump? Damit ich auch Kommentare im asm-Code haben kann -fverbose-asm im gcc?
– Hirte
10. Januar 2020 um 17:08 Uhr
@Herdsman: Das kannst du nicht. Das zusätzliche Zeug -fverbose-asm fügt hinzu, hat die Form von Kommentaren in der asm-Syntax der Ausgabe, nicht von Direktiven, die etwas Zusätzliches in die einfügen .o Datei. Es wird alles zur Montagezeit verworfen. Sehen Sie sich die Ausgabe des Compilers asm an stattdessen der Demontage, zB auf godbolt.org wo Sie es einfach mit der Quellzeile per Mouseover und farblicher Hervorhebung der entsprechenden Quell- / ASM-Zeilen abgleichen können. Wie entferne ich “Rauschen” aus der GCC/Clang-Assembly-Ausgabe?
– Peter Cordes
9. Mai 2020 um 19:16 Uhr
Andreas Keeton
Verwenden Sie den Schalter -S (Anmerkung: großes S) für GCC, und der Assemblercode wird in eine Datei mit der Erweiterung .s ausgegeben. Beispielsweise der folgende Befehl:
gcc -O2 -S foo.c
belässt den generierten Assembler-Code in der Datei foo.s.
Sie sollten -c und -S nicht mischen, sondern nur eines davon verwenden. In diesem Fall überschreibt das eine das andere, wahrscheinlich abhängig von der Reihenfolge, in der sie verwendet werden.
– Adam Rosenfield
17. August 2009 um 19:28 Uhr
@AdamRosenfield Gibt es einen Hinweis darauf, dass -c und -S nicht gemischt werden sollten? Wenn es wahr ist, sollten wir den Autor möglicherweise daran erinnern und es bearbeiten.
Wenn Sie alle Zwischenausgänge wünschen, verwenden Sie gcc -march=native -O3 -save-temps. Sie können immer noch verwenden -c bei der Erstellung von Objektdateien anzuhalten, ohne zu versuchen, eine Verknüpfung herzustellen, oder was auch immer.
– Peter Cordes
2. Juni 2018 um 1:21 Uhr
-save-temps ist interessant, da es auf einen Schlag den genauen generierten Code ausgibt, während die andere Option den Compiler mit aufruft -S bedeutet zweimal kompilieren und möglicherweise mit unterschiedlichen Optionen. Aber-save-temps speichert alles im aktuellen Verzeichnis, was ziemlich chaotisch ist. Sieht so aus, als wäre es eher als Debug-Option für GCC gedacht als als Werkzeug zur Überprüfung Ihres Codes.
– Stéphane Gourichon
22. Januar 2020 um 18:16 Uhr
amaterasu
Verwendung der -S Der Wechsel zu GCC auf x86-basierten Systemen erzeugt standardmäßig einen Dump der AT&T-Syntax, die mit angegeben werden kann -masm=att schalten, so:
gcc -S -masm=att code.c
Wenn Sie hingegen einen Dump in Intel-Syntax erstellen möchten, können Sie die verwenden -masm=intel schalten, so:
gcc -S -masm=intel code.c
(Beide produzieren Dumps von code.c in ihre verschiedene Syntax, in die Datei code.s beziehungsweise)
Um ähnliche Effekte mit objdump zu erzeugen, sollten Sie die verwenden --disassembler-options=intel/att switch, ein Beispiel (mit Code-Dumps zur Veranschaulichung der Unterschiede in der Syntax):
Gottriegel ist ein sehr nützliches Tool, das nur C++-Compiler auflistet, die Sie verwenden können -x c Flag, damit es den Code als C behandelt. Es wird dann nebeneinander eine Assemblyliste für Ihren Code generiert, und Sie können die verwenden Colourise Option zum Generieren farbiger Balken, um visuell anzuzeigen, welcher Quellcode der generierten Assembly zugeordnet ist. Zum Beispiel der folgende Code:
Es wäre schön zu wissen, wie Godbolt-Filter funktionieren: .LC0, .text, // und Intel. Intel ist einfach -masm=intel aber was ist mit dem Rest?
– Z-Boson
22. Februar 2017 um 8:01 Uhr
Ich denke, es wird hier erklärt: stackoverflow.com/a/38552509/2542702
– Z-Boson
22. Februar 2017 um 8:02 Uhr
Godbolt unterstützt C (zusammen mit einer Menge anderer Sprachen wie Rust, D, Pascal …). Es gibt nur viel weniger C-Compiler, also ist es immer noch besser, C++-Compiler zu verwenden -x c
– phuklv
27. April 2019 um 9:34 Uhr
Warum unterscheiden sich die Saiten zwischen der Quelle und der Baugruppe? Der Zeilenumbruch wurde am Ende entfernt
– OmarL
19. März 2021 um 10:38 Uhr
Hast du versucht gcc -S -fverbose-asm -O source.c Dann schauen Sie in die generierte source.s Assembler-Datei?
Der generierte Assembler-Code geht hinein source.s (Sie könnten das mit überschreiben -oAssembler-Dateiname ); das -fverbose-asm Option fordert den Compiler auf, einige Assembler-Kommentare auszugeben, die den generierten Assembler-Code “erklären”. Das -O Option fordert den Compiler auf, ein wenig zu optimieren (es könnte mehr optimieren mit -O2 oder -O3).
Wenn Sie was verstehen wollen gcc tut Versuch vorbei -fdump-tree-all aber seien Sie vorsichtig: Sie erhalten Hunderte von Dump-Dateien.
BTW, GCC ist durch erweiterbar Plugins oder mit SCHMELZEN (eine hochrangige domänenspezifische Sprache zur Erweiterung von GCC; die ich 2017 aufgegeben habe)
Es wäre schön zu wissen, wie Godbolt-Filter funktionieren: .LC0, .text, // und Intel. Intel ist einfach -masm=intel aber was ist mit dem Rest?
– Z-Boson
22. Februar 2017 um 8:01 Uhr
Ich denke, es wird hier erklärt: stackoverflow.com/a/38552509/2542702
– Z-Boson
22. Februar 2017 um 8:02 Uhr
Godbolt unterstützt C (zusammen mit einer Menge anderer Sprachen wie Rust, D, Pascal …). Es gibt nur viel weniger C-Compiler, also ist es immer noch besser, C++-Compiler zu verwenden -x c
– phuklv
27. April 2019 um 9:34 Uhr
Warum unterscheiden sich die Saiten zwischen der Quelle und der Baugruppe? Der Zeilenumbruch wurde am Ende entfernt
Beachten Sie, dass „Bytecode“ normalerweise den Code bezeichnet, der von einer VM wie JVM oder der CLR von .NET verwendet wird. Die Ausgabe von GCC wird besser als “Maschinencode”, “Maschinensprache” oder “Assemblersprache” bezeichnet.
– Javier
17. August 2009 um 19:27 Uhr
Ich habe eine Antwort mit Godbolt hinzugefügt, da es ein sehr leistungsfähiges Tool ist, um schnell damit zu experimentieren, wie sich verschiedene Optionen auf Ihre Codegenerierung auswirken.
– Shafik Yaghmour
12. September 2014 um 2:35 Uhr
stackoverflow.com/a/19083877/995714
– phuklv
30. November 2014 um 6:33 Uhr
Weitere Tipps, wie Sie die Ausgabe von asm für Menschen lesbar machen, finden Sie unter: Wie entferne ich „Rauschen“ aus der Ausgabe der GCC/Clang-Assembly?
– Peter Cordes
5. September 2016 um 20:46 Uhr
Hier beantwortet: stackoverflow.com/questions/137038/… Verwenden Sie die Option -S für gcc (oder g++).
– wissen ist Macht
26. Juli 2017 um 19:38 Uhr