2012-08-02 8 views
21

Ich habe versucht, this page sowie verschiedene andere Anleitungen zu verwenden, um herauszufinden, wie sehr einfache ARM-Anweisungen als Binär-und Hexadezimal auszudrücken. Es scheint, als sollte es ein einfacher Prozess für mich sein, aber ich verstehe es immer noch nicht. Hier ein paar Beispiele.Konvertieren sehr einfache ARM-Anweisungen in binär/hex

Grund NOP:

 what goes here?   what goes here? 
      _↓_     _____↓____ 
      | |    |   | 
mov r0, r0 ; ????00?1101????????????????????? 
         |__||__| 
          ↑ ↑ 
       how do I express registers? 

gleiche grundlegende Frage für die anderen.

Vergleicht man zwei Register:

cmp r1, r0 

sofort Mehrwert registrieren:

add r0, #0x1a 

All diese Online-Tutorials sind hervorragend bei der beschreibt, wie Anweisungen wie diese verwenden, aber keiner konnte ich um herauszufinden, wie man einen ARM-Befehl in den binären/hexadezimalen/Maschinencode umwandelt, in den er eingebaut wird.

Vielen Dank im Voraus für Ihre Hilfe.

+2

große Frage; Leider ist die Verbindung tot. Für Leute, die vorbeikommen, hier ist ein kurzer [Webarchivlink] (https://web.archive.org/web/20150426195854/http://www.nyx.net/~troddis/ARM.html) – Asu

Antwort

29

Hier ist, wie Datenverarbeitungsanweisungen codiert sind:

ARM data processing instructions

Sie haben Tabelle Bedingungscodes in der Seite von Ihnen. Die Register sind 0000 bis 1111 codiert.

Alle Ihre Beispiele fallen unter die gleiche Kategorie. Das Bild wird aus einem Dokument auf meiner Festplatte extrahiert, aber ich habe es auch gefunden google. Diese Anweisungen zu codieren ist eine mühsame Aufgabe.

So sollte mov r0, r0 so gehen:

1110 00 0 0 1101 0000 0000 00000000 

I Rn setzen auf 0, weil es nicht wirklich für MOV ist. Im Fall von CMP, glaube ich, S ist immer 1.

5

Sie sollten eine Kopie des ARM ARM erhalten beschreibt es die Codierung für alle Anweisungen.

Die meisten ARM-Befehle verwenden die oberen 4 Bits für einen bedingten Code. Wenn Sie den Befehl nicht bedingt ausführen wollen, verwenden Sie einfach die Pseudo-Bedingung AL (1110).

Das erste Register (Rn) in der Kodierung wird nicht für den MOV-Befehl verwendet und sollte wie vom ARM ARM definiert auf 0000 gesetzt werden.

Das zweite Register ist das Ziel, hier gibt es nur die Registernummer kodieren, so in Ihrem Fall wäre es auch 0000 sein, weil Sie r0 als destinal verwenden, für r4 wäre es 0100.

Das sein Rest ist der sogenannte Shifter-Operand, der sehr flexibel ist. Es könnte ein einfaches Register sein wie in Ihrem Fall (r0), dann ist es nur 0000 0000 0000, wo die letzten 4 Bits wieder das Register codieren. Es kann auch verschiedene Arten von Verschiebungen codieren und rotiert mit Register- oder unmittelbaren Werten für die Datenverarbeitung.

Es könnte aber auch eine unmittelbare sein, wo 8 Bits in den unteren Bits codiert sind und die ersten 4 Bits eine rechte Drehung in 2-Bit-Schritten definieren. In diesem Fall ist Bit25 auch 1, in allen anderen Fällen ist es 0.

+5

ARM ARM ist ein Spaß Akronym, aber es ist furchtbar schwer, eine Google-Suche für sie zu tun. Die Erweiterung ist 'ARM Architecture Reference Manual', und sie sind [hier] verfügbar (http://infocenter.arm.com/help/topic/com.arm.docsset.architecture.reference/index.html#reference) nach einer kostenlosen Registrierung. –

+0

@Kevin Nein, die Erweiterung ist tatsächlich ** Advanced (Reduce Instruction Set Computing) Maschinenarchitektur Referenzhandbuch **. Aber das ist keine gute Google-Suche :) –

9

Zunächst benötigen Sie das ARM Architectural Reference Manual (ARM ARM) auf infocenter.arm.com, Referenzhandbücher, erhalten die älteste (armv5 oder Wasauchimmer). Der Befehlssatz ist darin gut definiert.

Zweitens, warum nicht einfach einige Anweisungen zusammenbauen und sehen, was passiert?

;@test.s 
cmp r1, r0 
add r0, #0x1a 

unabhängig Quer Assembler Sie haben (http://github.com/dwelch67/raspberrypi im Build gcc-Verzeichnis für ein Skript sehen, die gerade laufen bis durch binutils in diesem Skript)

arm-none-linux-gnueabi-as test.s -o test.o 
arm-none-linux-gnueabi-objdump -D test.o 

Arm-none-linux-gnueabi vs arm- keine-elf vs Arm-elf, etc. Dont für diese Angelegenheit, die alle die gleichen

Disassembly of section .text: 

00000000 <.text>: 
    0: e1510000 cmp r1, r0 
    4: e280001a add r0, r0, #26 

die oberen vier Bits eines vollen 32-Bit-ARM-Befehls tun (nicht Daumen) sind der Bedingungscode finden Sie im Bedingungsfeld Abschnitt in der ARM ARM. Eine 0xE bedeutet immer, immer diese Anweisung auszuführen. 0b0000 wird nur ausgeführt, wenn das z-Flag gesetzt ist, 0b0001 ne nur ausführen, wenn z frei ist, etc.

In den ARM ARM drücken in den Arm Befehlssatz, dann alphabetische Liste der Arm Anweisungen, dann finden Sie cmp Es beginnt mit cond 00I10101 rn sbz shifter

Von unserer CMP-Anweisung oben sehen wir 1110 000101010001 ... also bin ich ein Null-Bits 15:12 sind Null-Bits 27:26 sind Null und 24:21 sind 1010, also ist dies ein CMP Anweisung

Bits 19 bis 16 oben sind 0b001 das ist rn so rn = 1 (r1) für den Shifter-Operand in der ARM ARM sagt Ihnen, Adressierungsmodus 1 Datenverarbeitungsoperanden zu betrachten und hat einen Link in der PDF zu die Seite

Wir wissen, dass wir wollen, dass der zweite Operand einfach ein Register ist, das Datenverarbeitungsoperanden - Register genannt wird, und eine Seitenzahl, gehen Sie zu dieser Seite auf dieser Seite 15:12 ist rd 11: 4 sind Nullen und 3 : 0 ist rm. wir wissen aus der cmp-anweisung, es heißt 15:12 sollte null sein, ich frage mich, ob es sich interessiert, ein cmp speichert ein ergebnis nicht in einem register, so dass rd nicht benutzt wird. rm verwendet wird und in diesem Fall wollen wir r0, also 0b0000 geht in 3: 0 auch beachten, dass es Bits 27:25 als Nullen zeigt, in der Cmp-Anweisung 25 ist ich, wir wissen jetzt, dass wir eine Null so wollen

zwischen der cmp Seite und dieser Datenverarbeitung - registrieren Seite haben wir das ganze Bild

1110 condition 
000 
1010 opcode 
1 S (store flags, that is a 1 for a cmp to be useful) 
0001 rn 
0000 rd/dont care/sbz 
00000 
000 
0000 rm 

cmp rn,rm 
cmp r1,r0 

das Add ähnlich ist, verwendet aber eine unmittelbare, so in der alpha-Liste von Anweisungen an den Additionsbefehl gehen. wir wissen jetzt von der cmp, dass 24:21 für diese klasse der anweisung der opcode ist, können wir ziemlich direkt zum shifter operand stuff gehen, um von dort aus fortzufahren

dieses mal machen wir add rd, rn, # sofort

so suchen die Seite für #immediate

und die Codierung ist

1110 condition, always 
001 (note the immediate bit is set) 
0100 (opcode for add for this type of instruction) 
0 (S not saving the flags, it would be adds r0,r0,#26 for that) 
0000 (rn = r0) 
0000 (rd = r0) 

nun der interessante Teil kommt, können wir die 26 verschiedene Arten kodieren.Bits 7: 0 sind die Unmittelbaren und Bits 11: 8 erlauben, dass Unmittelbar gedreht wird, 26 ist 0x1A, wir könnten einfach 0x1A in die unteren 8 Bits setzen und die Drehung auf 0 setzen, und das ist, was Gnu-Assembler getan hat. könnte wahrscheinlich eine 0x68 in den unteren 8 Bits setzen und eine 1 im route_imm Feld 1101000 nach rechts gedreht 1 * 2 Bits ist 11010 = 0x1A = 26.