Baugruppencode vs Maschinencode vs Objektcode?

227

Was ist der Unterschied zwischen Objektcode, Maschinencode und Baugruppencode?

Können Sie ein visuelles Beispiel für ihren Unterschied geben?

mmcdole
quelle
Ich bin auch neugierig, woher der Name "Objektcode" stammt. Was soll das Wort "Objekt" darin bedeuten? Hat es etwas mit objektorientierter Programmierung zu tun oder nur mit einem Zusammentreffen von Namen?
SasQ
@ SasQ: Objektcode .
Jesse Good
Ich frage nicht nach einem Objektcode, Captain Obvious. Ich frage, woher der Name kommt und warum er "Objekt" -Code heißt.
BarbaraKwarc

Antworten:

296

Maschinencode ist Binärcode (1 und 0), der direkt von der CPU ausgeführt werden kann. Wenn Sie eine Maschinencodedatei in einem Texteditor öffnen würden, würden Sie Müll sehen, einschließlich nicht druckbarer Zeichen (nein, nicht diese druckbaren Zeichen;)).

Objektcode ist ein Teil des Maschinencodes, der noch nicht zu einem vollständigen Programm verknüpft wurde. Es ist der Maschinencode für eine bestimmte Bibliothek oder ein bestimmtes Modul, aus dem das fertige Produkt besteht. Es kann auch Platzhalter oder Offsets enthalten, die nicht im Maschinencode eines abgeschlossenen Programms enthalten sind. Der Linker verwendet diese Platzhalter und Offsets, um alles miteinander zu verbinden.

Assembler-Code ist Klartext und (etwas) lesbarer Quellcode, der meistens ein direktes 1: 1-Analogon mit Maschinenanweisungen enthält. Dies wird mithilfe von Mnemonics für die eigentlichen Anweisungen, Register oder anderen Ressourcen erreicht. Beispiele sind JMPund MULTfür die Sprung- und Multiplikationsanweisungen der CPU. Im Gegensatz zum Maschinencode versteht die CPU den Baugruppencode nicht. Sie konvertieren Assembler-Code mithilfe eines Assemblers oder eines Compilers in eine Maschine. Wir denken jedoch normalerweise an Compiler in Verbindung mit einer höheren Programmiersprache, die weiter von den CPU-Anweisungen entfernt sind.

Zum Erstellen eines vollständigen Programms müssen Sie den Quellcode für das Programm entweder in Assembly oder in einer höheren Sprache wie C ++ schreiben . Der Quellcode wird zu Objektcode zusammengestellt (für Assembler-Code) oder kompiliert (für höhere Sprachen), und einzelne Module werden miteinander verbunden, um der Maschinencode für das endgültige Programm zu werden. Bei sehr einfachen Programmen ist der Verknüpfungsschritt möglicherweise nicht erforderlich. In anderen Fällen, z. B. bei einer IDE (integrierte Entwicklungsumgebung), können Linker und Compiler zusammen aufgerufen werden. In anderen Fällen kann ein kompliziertes Make- Skript oder eine Lösungsdatei verwendet werden, um der Umgebung mitzuteilen, wie die endgültige Anwendung erstellt werden soll.

Es gibt auch interpretierte Sprachen , die sich anders verhalten. Interpretierte Sprachen basieren auf dem Maschinencode eines speziellen Dolmetscherprogramms. Auf der Basisebene analysiert ein Interpreter den Quellcode und konvertiert die Befehle sofort in neuen Maschinencode und führt sie aus. Moderne Interpreter, manchmal auch als Laufzeitumgebung oder virtuelle Maschine bezeichnet , sind viel komplizierter: Sie können ganze Abschnitte des Quellcodes gleichzeitig auswerten, nach Möglichkeit zwischenspeichern und optimieren und komplexe Speicherverwaltungsaufgaben erledigen. Eine interpretierte Sprache kann auch in eine untergeordnete Zwischensprache oder einen Bytecode vorkompiliert werden, ähnlich wie Assembler-Code.

Joel Coehoorn
quelle
24
+1: nette, aber etwas vereinfachende Antwort - nicht alle Montageanweisungen werden 1: 1 in Maschinenanweisungen übersetzt, und Objektdateien können auch andere Daten enthalten (Umzugsinformationen, Symboltabellen, ...)
Christoph
5
Es wurde ein Wieselwort für Ihre erste Ausgabe hinzugefügt, das bearbeitet wurde, um die zweite Ausgabe klarer zu machen.
Joel Coehoorn
2
@Christoph: Sie sagen "nicht alle Montageanleitungen werden 1: 1 in Maschinenanweisungen übersetzt", bitte geben Sie ein Beispiel.
Olof Forshell
5
@Olof: RISC-Architekturen bieten manchmal einen virtuellen Befehlssatz auf Assembly-Ebene - z. B. MIPS-Pseudoanweisungen ( en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions )
Christoph
3
@Panzercrisis Vom Assembler wird nichts hinzugefügt. Es ist eine direkte Übersetzung dessen, was Sie geschrieben haben, in tatsächliche Maschinenanweisungen. Und ich würde den zusätzlichen Code, den die Compiler eingeben, nicht als "unnötig" bezeichnen
Joel Coehoorn,
125

Die anderen Antworten gaben eine gute Beschreibung des Unterschieds, aber Sie fragten auch nach einem Bild. Hier ist ein Diagramm, das zeigt, wie sie vom C-Code zu einer ausführbaren Datei gelangen.

Grafik Noob
quelle
3
Ich finde das wirklich hilfreich, aber es fehlt das Etikett "Maschinencode"
Alexx Roche
Wenn es sich also um ausführbaren Code handelt, entspricht dies dem Maschinencode?
CMCDragonkai
3
Im Kontext dieses Diagramms ist der "Objektcode" der Maschinencode.
Grafik Noob
5
Tatsächlich sind sowohl der Objektcode als auch der ausführbare Code Maschinencodes. Der Unterschied besteht darin, dass der Objektcode nicht das abgeschlossene Programm ist. Es muss mit anderen Hilfsbibliotheks- / Modulcodes wie im Diagramm angegeben kombiniert werden, um ein vollständiges ausführbares Programm / Code zu bilden.
okey_on
@okeyxyz auf welcher Ebene wäre es richtig zu sagen, dass es direkt vom Prozessor ausgeführt wird? Nach dem Assembler, nach dem Linker, nach dem Loader, nachdem er zum Mikrocontroller konvertiert wurde?
Celeritas
49

Der Assembler-Code ist eine lesbare Darstellung des Maschinencodes:

mov eax, 77
jmp anywhere

Maschinencode ist reiner Hexadezimalcode:

5F 3A E3 F1

Ich nehme an, Sie meinen Objektcode wie in einer Objektdatei. Dies ist eine Variante des Maschinencodes, mit dem Unterschied, dass die Sprünge so parametrisiert sind, dass ein Linker sie ausfüllen kann.

Ein Assembler wird verwendet, um Assembler-Code in Maschinencode (Objektcode) zu konvertieren. Ein Linker verknüpft mehrere Objekt- (und Bibliotheks-) Dateien, um eine ausführbare Datei zu generieren.

Ich habe einmal ein Assembler-Programm in reinem Hex geschrieben (kein Assembler verfügbar), zum Glück war dies vor langer Zeit auf dem guten alten (alten) 6502. Aber ich bin froh, dass es Assembler für die Pentium-Opcodes gibt.

Toon Krijthe
quelle
76
Nein nein Nein Nein. Maschinencode ist kein Hex-Code. es ist rein binär. Hex-Code ist nur eine bequeme Darstellung von Binär.
Bretonischer
56
Wenn wir wirklich in Extreme gehen, ist es nicht binär, sondern eine Menge gespeicherter Elektrizität in einem Stromkreis. ;-)
Toon Krijthe
17
Ja natürlich. Es gibt eine Beziehung zwischen dem hexidecimal, und was würden Sie „Maschinencode“ nennen, aber es ist nicht ganz richtig zu sagen , hexidecimal ist Maschinencode. Das ist alles was ich versuche zu sagen.
Breton
9
@Breton In diesem Sinne gibt es keinen "Hex-Code", oder? "Hex-Code" ist nur eine Möglichkeit, den Maschinencode anzuzeigen. Sie können den Maschinencode hexadezimal, binär, oktal, dezimal oder nach Belieben anzeigen. Auch in diesem Sinne gibt es auch keinen "Binärcode". Auch hier ist "Binärcode" nur eine Möglichkeit, den Maschinencode anzuzeigen.
Utku
9
@Breton Was Sie sagen, macht nicht wirklich viel Sinn. Binär ist eine Art der Darstellung, genau wie Hex. Wenn es nicht hex ist, ist es auch nicht binär.
Koray Tugay
18

8B 5D 32 ist Maschinencode

mov ebx, [ebp+32h] ist Montage

lmylib.soenthält 8B 5D 32ist Objektcode

Quassnoi
quelle
8

Ein Punkt, der noch nicht erwähnt wurde, ist, dass es einige verschiedene Arten von Assembler-Code gibt. In der einfachsten Form müssen alle in Anweisungen verwendeten Zahlen als Konstanten angegeben werden. Beispielsweise:

$ 1902: BD 37 14: LDA $ 1437, X.
$ 1905: 85 03: STA $ 03
$ 1907: 85 09: STA $ 09
$ 1909: CA: DEX
$ 190A: 10: BPL $ 1902

Wenn das obige Codebit unter der Adresse $ 1900 in einer Atari 2600-Kassette gespeichert ist, werden mehrere Zeilen in verschiedenen Farben angezeigt, die aus einer Tabelle abgerufen wurden, die bei der Adresse $ 1437 beginnt. Bei einigen Tools werden durch Eingabe einer Adresse zusammen mit dem am weitesten rechts stehenden Teil der obigen Zeile die in der mittleren Spalte angezeigten Werte gespeichert und die nächste Zeile mit der folgenden Adresse begonnen. Das Eingeben von Code in dieser Form war viel bequemer als das Eingeben von Hex, aber man musste die genauen Adressen von allem kennen.

Die meisten Assembler erlauben die Verwendung symbolischer Adressen. Der obige Code würde eher wie folgt geschrieben:

rainbow_lp:
  lda ColorTbl, x
  sta WSYNC
  sta COLUBK
  dex
  bpl rainbow_lp

Der Assembler würde den LDA-Befehl automatisch so anpassen, dass er sich auf die Adresse bezieht, die dem Label ColorTbl zugeordnet ist. Die Verwendung dieses Assembler-Stils erleichtert das Schreiben und Bearbeiten von Code erheblich, als dies möglich wäre, wenn alle Adressen von Hand eingegeben und verwaltet werden müssten.

Superkatze
quelle
1
+1. Noch ein zusätzlicher Punkt: Es gibt auch verschiedene Assembler- Syntaxen , von denen Intel und AT & T am bekanntesten sind .
informatik01
1
@ informatik01: Wie wäre es mit Intel 8080 Mnemonics gegen Zilog Z80? Ich würde vermuten, dass dies vor dem Syntaxkrieg zwischen Intel und AT & T liegt.
Supercat
Ohne zu streiten, erwähnte ich nur diesen Aspekt (unterschiedliche Syntax) und gab ein Beispiel für zwei populärste / bekannteste / berühmteste Syntaxen.
informatik01
4

Quellcode, Baugruppencode, Maschinencode, Objektcode, Bytecode, ausführbare Datei und Bibliotheksdatei.

All diese Begriffe sind für die meisten Menschen oft sehr verwirrend, da sie glauben , dass sie sich gegenseitig ausschließen . Sehen Sie sich das Diagramm an, um ihre Beziehungen zu verstehen. Die Beschreibung jedes Begriffs ist unten angegeben.


Codetypen


Quellcode

Anweisungen in lesbarer (Programmier-) Sprache


Übergeordneter Code

Anweisungen, die in einer höheren (Programmier-) Sprache geschrieben sind,
z. B. C-, C ++ - und Java-Programme


Baugruppencode

Anweisungen in einer Assemblersprache (eine Art Low-Level-Programmiersprache). Als erster Schritt des Kompilierungsprozesses wird übergeordneter Code in dieses Formular konvertiert. Es ist der Baugruppencode, der dann in den tatsächlichen Maschinencode konvertiert wird. Auf den meisten Systemen werden diese beiden Schritte im Rahmen des Kompilierungsprozesses automatisch ausgeführt.
zB program.asm


Objektcode

Das Produkt eines Kompilierungsprozesses. Es kann in Form von Maschinencode oder Bytecode vorliegen.
zB file.o


Maschinensprache

Anleitung in Maschinensprache.
zB a.out


Bytecode

Anweisung in einer Zwischenform, die von einem Interpreter wie JVM ausgeführt werden kann.
zB Java-Klassendatei


Ausführbare Datei

Das Produkt des Verknüpfungsprozesses. Es handelt sich um Maschinencode, der direkt von der CPU ausgeführt werden kann.
zB eine EXE-Datei.

Beachten Sie, dass in einigen Kontexten eine Datei, die Anweisungen für Bytecode oder Skriptsprache enthält, auch als ausführbar angesehen werden kann.


Bibliotheksdatei

Einige Codes werden aus verschiedenen Gründen wie der Wiederverwendbarkeit in dieses Formular kompiliert und später von ausführbaren Dateien verwendet.

Bertram Gilfoyle
quelle
1
Ich würde argumentieren, dass nicht jede Versammlung wirklich eine Quelle im strengsten Sinne von Code ist, der von Menschen geschrieben und / oder gepflegt wird. Oft wird es maschinell aus dem Quellcode generiert und ist nie für den menschlichen Gebrauch bestimmt (z. B. erstellt gcc wirklich asm-Text, den es einem separaten Assembler zuführt, anstatt einen integrierten Assembler in der cc1ausführbaren Datei zu haben). Ich denke, der Asm-Kreis sollte auf der linken Seite des "Quell" -Kreises herausragen, da einige Asm nur Asm sind, keine Quelle. Es ist natürlich nie Objektcode , aber einige asm sind ein Schritt auf dem Weg von der Quelle zu den Objektdateien.
Peter Cordes
@ PeterCordes Vielen Dank für den Kommentar. Mir war nicht bewusst, was Sie über die Arbeit von gcc gesagt haben. Ich fürchte jedoch, wenn ich Ihnen vollkommen zustimmen kann. Ich meine, Quellcode ist etwas, das mit einer für Menschen lesbaren Programmiersprache geschrieben wurde. Es kann von Menschen geschrieben oder gepflegt werden oder nicht. Ich bin sicher, dass Sie Transcompiler kennen werden. In welche Kategorie werden Sie aus Ihrer Sicht das Produkt eines solchen Compilers einordnen? Quellcode oder etwas anderes? Bitte korrigieren Sie mich, wenn ich falsch liege. Weitere Kommentare sind immer willkommen.
Bertram Gilfoyle
1

Der Assembler-Code wird hier erläutert .

"Eine Assemblersprache ist eine einfache Sprache zum Programmieren von Computern. Sie implementiert eine symbolische Darstellung der numerischen Maschinencodes und anderer Konstanten, die zum Programmieren einer bestimmten CPU-Architektur erforderlich sind."

Der Maschinencode wird hier besprochen .

"Maschinencode oder Maschinensprache ist ein System von Anweisungen und Daten, die direkt von der Zentraleinheit eines Computers ausgeführt werden."

Grundsätzlich ist Assembler-Code die Sprache und wird von einem Assembler (analog zu einem Compiler) in Objektcode (den nativen Code, den die CPU ausführt) übersetzt.

rbrayb
quelle
1

Ich denke, das sind die Hauptunterschiede

  • Lesbarkeit des Codes
  • Kontrolle darüber, was Ihr Code tut

Durch die Lesbarkeit kann der Code 6 Monate nach seiner Erstellung mit geringem Aufwand verbessert oder ersetzt werden. Wenn die Leistung jedoch kritisch ist, möchten Sie möglicherweise eine einfache Sprache verwenden, um auf die spezifische Hardware zuzugreifen, die Sie in der Produktion haben schnellere Ausführung.

IMO-Computer sind heute schnell genug, um einem Programmierer eine schnelle Ausführung mit OOP zu ermöglichen.

Alberto Zaccagni
quelle
1

Assembly sind kurze beschreibende Begriffe, die Menschen verstehen können und die direkt in den Maschinencode übersetzt werden können, den eine CPU tatsächlich verwendet.

Assembler ist zwar für den Menschen etwas verständlich, aber immer noch auf niedrigem Niveau. Es braucht viel Code, um etwas Nützliches zu tun.

Stattdessen verwenden wir höhere Sprachen wie C, BASIC, FORTAN (OK, ich weiß, dass ich mich selbst datiert habe). Beim Kompilieren erzeugen diese Objektcode. Frühe Sprachen hatten Maschinensprache als Objektcode.

Viele heutige Sprachen wie JAVA und C # werden normalerweise zu einem Bytecode kompiliert, der kein Maschinencode ist, sondern zur Laufzeit leicht interpretiert werden kann, um Maschinencode zu erzeugen.

Jim C.
quelle
Ihr Kommentar zu Java und C # - beide verwenden die Just In Time-Kompilierung, damit Bytecodes nicht interpretiert werden. C # (.NET im Allgemeinen) wird in Intermediate Language (IL) kompiliert, die dann für die Ziel-CPU in die native Maschinensprache JITed wird.
Craig Shearer
-1

Die Quelldateien Ihrer Programme werden zu Objektdateien kompiliert. Anschließend verknüpft der Linker diese Objektdateien miteinander und erstellt eine ausführbare Datei mit den Maschinencodes Ihrer Architektur.

Sowohl die Objektdatei als auch die ausführbare Datei enthalten den Maschinencode der Architektur in Form von druckbaren und nicht druckbaren Zeichen, wenn er von einem Texteditor geöffnet wird.

Die Dichotomie zwischen den Dateien besteht jedoch darin, dass die Objektdatei (en) möglicherweise ungelöste externe Referenzen enthalten (z. printfB.). Daher muss es möglicherweise mit anderen Objektdateien verknüpft werden. Das heißt, die nicht aufgelösten externen Referenzen müssen aufgelöst werden, um die anständige ausführbare ausführbare Datei durch Verknüpfen mit anderen Objektdateien wie C / C ++ - Laufzeitbibliotheken zu erhalten .

snr
quelle