Was passiert, wenn Baugruppencode in Objektcode übersetzt wird?

608
Panther Coder

Ich interessiere mich für die Entwicklung von Systemsoftware. Ich habe die Arbeit eines Compilers seit einigen Tagen analysiert. Ein Assembly-Code, der von einem Compiler (etwa) generiert wird, clc hat einen Opcode, f8und ich bin sicher, dass der Assembler, der die obige Mnemonic zusammensetzt, den Opcode f8an seiner Stelle ersetzt.

Was mich stört, sind die Nachwirkungen dieser Phase (ich kenne die Linking-Phase dazwischen).

Ich meine, was genau passiert nach dieser Etappe? Angenommen, die endgültige ausführbare Datei ist eine unformatierte Binärdatei. Bedeutet das, dass der Opcode f8in binäre Daten umgewandelt 1111 1000und in der Datei gespeichert wird?

Wenn dies der Fall ist, warum kann ich dann den binären Inhalt einer Binärdatei nicht mit einem normalen Texteditor (z. B. Notepad) anzeigen - schließlich sind es '0' und '1'.

1
* "Ich kenne die Linking-Phase dazwischen" * - Falsch, die Linking-Stufe wäre * nach * Assemby. * "Was genau passiert nach dieser Phase" * - Abhängig davon, ob die Assembly einen verschiebbaren Objektcode (der mit anderen Objektdateien verknüpft sein könnte) oder einen absoluten Objektcode erzeugt. * "Immerhin sind es 0 und 1" * - Ja, aber ein Texteditor behandelt diese binären Daten immer als Codes für Text (z. B. ASCII), während ein ** Disassembler ** die Daten als Maschinencode behandelt. und Opcodes und Operanden anzeigen. sawdust vor 7 Jahren 0
Ihnen fehlt ein Schlüsselpunkt, "f8" muss nicht "konvertiert" werden, es ist bereits * "1111 1000", es handelt sich lediglich um unterschiedliche Darstellungen der gleichen Sache. Einer ist als Hex dargestellt, der andere als Binär. Hex hat den Vorteil, dass es von Menschen etwas lesbarer ist, und hat einen ordentlichen Nebeneffekt, wenn binäre Quads in einzelne Ziffern aufgeteilt werden. In diesem Fall sind f = 1111 und 8 = 1000. Die von der CPU verwendete Basiseinheit sind binäre Ziffern, jedoch neigen Menschen dazu Verwenden Sie die Hex-Darstellungen. Mokubai vor 7 Jahren 1

1 Antwort auf die Frage

2
Alex

Verwenden Sie zuerst immer das richtige Werkzeug für den Job. Der Texteditor zum Anzeigen von Binärdateien ist derselbe wie ein Messer zum Nageln. Verwenden Sie einen HEX-Viewer / -Editor für solche Aufgaben oder verwenden Sie besser das Tool, das die Interna der betreffenden Binärdatei kennt. Wenn wir über die Opcodes der CPU sprechen, wäre etwas wie IDA Pro free oder OllyDbg hilfreich für die Analyse interner ausführbarer Dateien.

Bedeutet das, dass der Opcode f8in binäre Daten umgewandelt 1111 1000und in der Datei gespeichert wird?

Wie von @Mokubai richtig angedeutet wurde - 0xF8ist dieselbe Zahl wie 1111 1000eine, die in HEX-Notation und die letzte als binäre Darstellung dargestellt wird. Im Dezimalsystem stimmt die Nummer 248 überein.

Wenn Sie manuell ausführbaren Code aus CPU-Opcodes erstellen (oder den Assembler-Quellcode kompilieren), erkennt die i386-CPU die Anweisung 0xF8( 0b11111000oder 248 - alles gleich) CLC.

Ein Assembly-Code, der von einem Compiler (etwa) generiert wird, clchat einen Opcode, f8und ich bin sicher, dass der Assembler, der die obige Mnemonic zusammensetzt, den Opcode f8an seiner Stelle ersetzt.

Das ist wahr, außer - "Ein von einem Compiler generierter Assembly-Code". Ich möchte nur sicherstellen, dass Sie den Unterschied zwischen "Assemblycode" und Opcodes richtig verstehen. Opcodes sind eine genaue Sprache, die von der CPU verstanden werden kann, es sind nur Zahlen (und so haben wir die ersten Computer programmiert, als Übersetzer von CPU-Mnemonics aka Assembler ein Traum waren).

Heutzutage verwenden wir hauptsächlich "direkte" Kompilierung von der höheren Programmiersprache direkt zu ausführbaren Binärdateien mit Compilern wie C / C ++ / GoLang, die CPU-Opcodes erzeugen.
(Wenn ich "direkte Kompilierung" gesagt habe, ist das eigentlich nicht wahr. Unter den Hauben-Compilern müssen mehrere Schritte ausgeführt werden, bevor ausführbare Binärdateien erstellt wurden. Für den Endbenutzer sieht es jedoch genauso aus, als würden wir ein Auto fahren, ohne zu wissen, wie Benzin in Bewegung umgewandelt wird.)

Wie von @sawdust im Kommentar richtig erwähnt, können Programmiersprachen höherer Ebenen unterschiedliche Strategien zum Erstellen von CPU-Opcodes verwenden. Sie können zum Beispiel den gccCompiler analysieren, wie er Opcodes garen würde, indem Sie ihm sagen, dass er Assembler-Code generiert, der zum Erstellen von Opcodes (Objektcodes) verwendet wird.

 gcc -S -o myprogram.asm myprogram.c 

Wenn dies der Fall ist, warum kann ich dann den binären Inhalt einer Binärdatei nicht mit einem normalen Texteditor (z. B. Notepad) anzeigen - schließlich sind es '0' und '1'.

Der Editor spricht eine andere Sprache. Es versteht seine eigenen "Opcodes" - ASCII, alles andere ist "griechisch" für Notepad.

* "Compiler wie C / C ++ / GoLang erstellen keinen" Assembler-Code ", sondern generieren Opcodes direkt." * - Möglicherweise können Sie eine Ausnahme auslösen, aber dies ist im Allgemeinen nicht der Fall. Ich habe mindestens drei C-Compiler verwendet, und alle drei erzeugten Assembly-Quellen, bevor Objektcode generiert wurde. Ich weiß das, weil ich optimierende Compiler-Fehler melden musste und die Assembler-Ausgabe verwendet habe, um zu beweisen, dass der Compiler fehlerhaften Code aus C generiert. sawdust vor 7 Jahren 1
Sie sind irreführend, indem Sie zustimmen, dass "f8" in binär konvertiert wird. Es findet keine eigentliche Konvertierung statt und muss nicht durchgeführt werden, es handelt sich lediglich um unterschiedliche Darstellungen derselben Sache. "f8" ist einfach eine für den Menschen besser lesbare Darstellung von "1111 1000". Mokubai vor 7 Jahren 0
@Mokubai Nein, ich habe nicht gesagt, dass 'f8' -> binär ist. Ich sagte 'clc` mnemonic -> `f8`, was' 11111000 'ist. "f8" und "11111000" sind nur eine andere Darstellung derselben Nummer Alex vor 7 Jahren 0
@sawdust Du hast recht, ich meinte "gcc -o binexe source.c". Ich werde meine Antwort korrigieren Alex vor 7 Jahren 0
Er stellt eine spezifische Frage, die Sie zitiert haben, und hat diese bejaht, dann geklärt. Ich bestreite nicht die Richtigkeit des folgenden Satzes, nur wenn ein direktes "Ja" als erster Teil Ihres Satzes bei der Beantwortung seiner Frage den Eindruck erwecken könnte, dass seine Annahme richtig war und dass ein zusätzlicher Konversionsschritt stattfindet . Das "Ja" zu entfernen, reicht aus. Mokubai vor 7 Jahren 0
@Mokubai Ohh, ich sehe jetzt was du meinst. Danke für die Hilfe ! Alex vor 7 Jahren 0
* "So haben wir die ersten Computer programmiert **, als Compiler von CPU-Mnemonics aka Assembler ein Traum waren" * - Behaupten Sie, so alt zu sein (UNIVAC verwendet zu haben) ?? !! Compiler sind keine Assembler und sollten zusammengeführt werden. Ich bezweifle, dass Sie länger als ich programmieren (dh seit 1967). Welchen Computer hatten Sie, der keinen Assembler hatte? FWIW Ich habe in Maschinencode geschrieben, aber nur für Patches auf Firmware. sawdust vor 7 Jahren 0
@sawdust UNIVAC mag Computer, was wir in der Universität auf Papierkarten programmiert haben, aber es hat mich nicht berührt. Meine Leidenschaft für die Computerwelt begann mit dem Intel 8080 auf einem benutzerdefinierten "Computer", der mit Hunderten von SN74LS74, SN74LS00 entwickelt und gebaut wurde ... die mit dem Rest der Welt nicht kompatibel sind, wo "Betriebssystem" in 8kb EPROM passt. Sie können sich vorstellen, wie viel "Spaß" es war, die ersten Versionen dieses Computers zu programmieren, indem Sie die Opcodes des Hardware-Programmierers eingeben und in das EPROM brennen. Später haben wir Assembler für diesen Comp geschrieben und es war einer der glücklichsten Momente in meinem Leben :) Alex vor 7 Jahren 0
@sawdust Sie haben Recht mit dem richtigen Begriff bezüglich Assembler, ich habe es korrigiert, Compiler -> Übersetzer. Ich sollte wahrscheinlich lange Erklärungen mit meinem Englisch vermeiden. Ich weiß es zu schätzen, dass Sie mir geholfen haben, meine Antwort zu korrigieren. Alex vor 7 Jahren 0
I'm pretty sure Intel had an assembler available; you just had to pay for it. But you probably did not have the peripherals to use it anyway. sawdust vor 7 Jahren 0
*"we mostly using direct compilation from high level programming language directly to executable binaries with compilers"* -- That's still a false statement. Just because a compiler has intermediate steps (such as generation of assemby language from HLL) that are not visible, that does not mean that there's a direct code generation. You're also ignoring the linking step. The typical executable the OP refers to is not a binary image, but probably a relocatable executable file that requires dynamic linking with shared libraries. sawdust vor 7 Jahren 0
@sawdust Ich denke nicht, dass wir mit tiefen Erklärungen beginnen müssen - "Wie Compiler funktionieren", wenn es um die Frage geht, "warum Opcodes nicht in Notepad zu sehen sind", aber ich freue mich über Ihre Kommentare, die zur Verbesserung meines Beitrags beigetragen haben ! Ich habe Klarstellung bezüglich "direkter Kompilierung" hinzugefügt. Alex vor 7 Jahren 0