2017-05-24 2 views
0

Ich habe eine einfache C++ Quelldatei mit dem folgenden Code erstellt.Assemblersprache zu Maschinencode

int main() { 
int a = 1; 
int b = 2; 
if(a < b) { 
    return 1; 
} 
else if(a > b) { 
    return 2; 
} 
else { 
    return 3; 
} 

}

benutzen ich objdump Befehl, um den Assembler-Code für das oben genannte Quellcode zu erhalten. Und die Linie

int b = 2; wird konvertiert in mov DWORD PTR [rbp-0x4], 0x2.

Und der entsprechende Maschinencode (Hex-Format) ist c7 45 fc 02 00 00 00.

Ich wollte wissen, wie kann ich Assemblercode in Binärcode konvertieren. Ich ging durch das Intel Reference Handbuch für x86-64, aber ich konnte das nicht verstehen, da ich neu in Low-Level-Programmierung bin.

+1

Was meinst du mit "konvertieren"? Ein Programm benutzen? Tun Sie es manuell? – Shiro

+0

Konvertierung manuell. –

+0

'int b = 2;' ist keine Assemblersprache.Der Unterschied ist, dass C kompilierte Sprache ist, also kann die Zeile "int b = 2;" auf viele verschiedene Arten implementiert werden (sogar vollständig vom Optimierer entfernt), je nachdem, welcher Compiler entscheiden wird, wie Maschinencode produziert wird Ergebnisse gemäß dem C-Standard. Die Assembler-Sprache unterscheidet sich in einer Weise, dass Assembler kein Compiler dieser Art ist. Wenn Sie in Assembly 'add rax, rbx' schreiben, wird das kompiliert, die Anweisung nicht geändert oder durch irgendeine Art von Optimierer entfernt das ist mehr wie "1: 1 Transformation". – Ped7g

Antwort

4

Sie sollten die Intel Handbücher lesen, es erklärt, wie man das macht. Für eine einfachere Referenz, read this. Die Art und Weise, wie x86-Anweisungen codiert sind, ist ziemlich einfach, aber die Anzahl der Möglichkeiten kann etwas überwältigend sein.

Auf den Punkt gebracht, umfasst ein x86-Befehl die folgenden Teile, wobei jeder Teil mit Ausnahme des Opcode fehlen werden:

prefix opcode operands immediate 

Das prefix Feld, um das Verhalten des Befehls ändern kann, was nicht gilt Ihr Anwendungsfall. Sie können die opcode in einer Referenz nachschlagen (ich mag this one), zum Beispiel mov r/m32, imm32 ist C7 /0 was bedeutet: Der Opcode ist C7 und einer der beiden Operanden ist Null als ein erweiterter Operand. Diese Anweisung nimmt ein 32-Bit-Sofort, so dass die Anweisung hat die Form

C7 operand/0 imm32 

Der Operand/extended Opcode als modr/m-Byte mit einem optionalen SIB (Skalenindex base) Byte für einige Adressierungsarten codiert ist und ein optionale 8-Bit- oder 32-Bit-Verschiebung. Sie können nachsehen, welchen Wert Sie benötigen in the reference. In Ihrem Fall wollen Sie also einen Speicheroperanden mit einer Ein-Byte-Verschiebung und einem Register-Operanden von 0 codieren, der zum modr/m-Byte 45 führt. So ist die Kodierung:

C7 45 disp8 imm32 

Jetzt codieren wir die 8-Bit-Verschiebung in Zweierkomplement. -4 entspricht FC, so ist dies

C7 45 FC imm32 

Schließlich kodieren wir das 32-Bit-Direkt, die Sie 2 sein wollen. Beachten Sie, dass es in Little Endian ist:

C7 45 FC 02 00 00 00 

Und so ist der Befehl codiert.

+0

So int die [link] (http://ref.x86asm.net/geek64.html) Sie zur Verfügung gestellt, ging ich zu C7 1 Byte Opcode, und es ist für ** MOV ** Anweisung. aber was bedeuten die beiden Operanden Evqp \t und Ivds \t bedeuten, entsprechen sie rm32 Adressierung und sofort? Danke für die Hilfe –

+0

Siehe [diese Seite] (http://ref.x86asm.net/#column_op) für die Bedeutung der Felder. Die Referenz, die ich verlinkt habe, ist stark komprimiert, aber schwieriger zu lesen. – fuz

+0

Okay, großartig. Eine weitere Frage war, dass Sie sagten: "Ich wollte rbp-Register mit 1 Byte Verschiebung (8 Bits) kodieren [** DWORD PTR [rbp-0x4] **]", als ich die Tabelle für MOD r/m in der [ link] (http://ref.x86asm.net/geek64.html#modrm_byte_32_64) Ich sehe auch eine Version von 32-Bit-Verschiebungen, können Sie mir ein Beispiel dafür geben? –

Verwandte Themen