Wie entschlüsselt man ARMv7-Anweisungen?

Ich versuche, die ARM-Befehlscodierung zu verstehen.

Das folgende Bild zeigt C-Code zusammen mit den entsprechenden Assembler-Anweisungen:

Geben Sie hier die Bildbeschreibung ein

Ich habe mir das ARMv7-Referenzhandbuch angesehen . Allerdings konnte ich den Zusammenhang zwischen dem Maschinencode und der entsprechenden Montageanleitung nicht finden.

Zum Beispiel,

Ich konnte den Maschinencode nicht zuordnen

F1AD0D08

zur Montageanleitung

sub.w sp, sp, #8

Können Sie mir dabei helfen?

=============================================== ====

Basierend auf den Antworten und nach einem Blick in das Referenzhandbuch habe ich die folgenden Informationen hinzugefügt.

Der Prozessorname ist Cortex-M4F .

Die Prozessorarchitektur des von mir verwendeten Mikrocontrollers ist ARMv7 .

Das verwendete Mikrocontroller-Profil ist insbesondere ARMv7-M .

Aus dem Handbuch :

ARMv7-M Das Mikrocontroller-Profil für Systeme , die nur den Thumb-Befehlssatz unterstützen und bei denen Gesamtgröße und deterministischer Betrieb für eine Implementierung wichtiger sind als absolute Leistung.

Bitte verlinken Sie auf das genaue Handbuch, von dem Sie sprechen.
@pipe Ich habe den Link im obigen Beitrag hinzugefügt.
Es ist nicht ARM7, es ist Thumb. Oder zumindest ein Teil davon (7808 = lrdb, 490D = pc-relative load).
@ pjc50 Könnten Sie erklären, wie "490D" dekodiert wird?
es ist armv7 (arm7 ist armv4). Es gibt den Arm-Anweisungssatz und den Daumen-Anweisungssatz und dann die Daumen2-Erweiterungen. das 490d ist ein daumen das sub.w ist ein daumen2. Schauen Sie sich in den armv7-Dokumenten die Unteranweisung an und dann die 32-Bit-thumb2-Codierung (en). Sehen Sie sich auch ldr und die Codierung thumb1 oder "All thumb variations" an.
@dwelch Ich bin ein bisschen verwirrt. Im Handbuch steht ARMv7, aber Sie sagten, arm7 sei armv4.
Die ARM-Versionsnummerierung ist fürchterlich verwirrend. Die Nummer auf dem Chip (kein V) ist völlig unabhängig von der Version des Befehlssatzes (mit einem V). zB "ARM926EJ-S"-Chips verwenden die "ARMv5TE"-Architektur. Mein "nicht ARM7"-Kommentar hat das V weggelassen und hätte auf jeden Fall "nicht 32-Bit-ARM" sagen sollen. dwelch ist richtig.
arm7 ist der Marketingname, der armv4 verwendet, arm9 verwendet armv5, arm11 verwendet armv6, dann gelangen Sie in den Cortex-a und Cortex-r, die armv7 (oder armv8) verwenden. armv7 != arm7. Ein Begriff ist die architektonische Nummerierung, der andere ein Produktname
und es gibt genug Unterschiede zwischen armv7(-ar) und armv7-m, dass es eine gute Idee ist, das m dort zu platzieren, wenn Sie über armv7-m sprechen.
Ja, verwirrend, schmerzhaft, detailliert usw. Die Alternative besteht darin, x86 allgemein zu sagen, um eine Vielzahl von Prozessoren abzudecken, die intern unterschiedlich sind (oder ihre Codenamen, Ivy Bridge, Sandy Bridge usw. zu verwenden, was sogar verwirrend ist, da einige das sind gleiche Architektur auf anderer Technologie 14nm statt 22)
Für diese spezielle Frage wird die Dekodierung dieser Anweisungen sowohl in den architektonischen Referenzhandbüchern armv7-m als auch armv7-ar behandelt, da thumb2 in beiden unterstützt wird.

Antworten (4)

Das ARMv7-M-Referenzhandbuch enthält keine Dekodierungs - Nachschlagetabelle, aber die Kodierung für jede Anweisung ist aufgelistet.

In dem von Ihnen verlinkten spezifischen Handbuch finden Sie dies im Abschnitt A6.7 - Alphabetical list of ARMv7-M Thumb instruction.

Diese enthält – wie gesagt – eine Liste aller Befehle und ihrer entsprechenden binären Kodierung. Zum Beispiel hat Seite A6-16 die binäre Codierung für die ADC (immediate)Anweisung. 11110...Wir können sehen, dass es mit zwei Wörtern beginnt und diese umfasst.

Das Problem geht "rückwärts". Das Handbuch enthält zwar alle notwendigen Informationen, ist aber schwer zu durchsuchen. Der Disassembler hat die Datenstrukturen, um das für Sie zu tun, und wenn Sie eine Tabelle wollen und es manuell tun, schlage ich vor, sich die Quellcodedateien für einen ARM-Disassembler anzusehen, zum Beispiel GNU binutils.

Als 68000-Architektur-Fan, der ich bin, ist es erwähnenswert, dass das M68000PM/AD -Referenzhandbuch für den 68000-Befehlssatz diese Umkehrtabelle enthält, die in binärer Reihenfolge geordnet ist, was diese Suche trivial macht.
Ein kurzer Blick in die Binutils-Quellen zeigt, dass der Code für den ARM-Disassembler hier zu finden ist

In ARMv7-m ARM, das ich mit der Codierung von T3 für Subtract Instant betrachte, das von der ARMv7-M-Architektur unterstützt wird, ist in der Form

SUB{S}<c>.W <Rd>,<Rn>,#<const>

das Bitmuster 11110i01101S.... das mit dem 0xF1A der Anweisung übereinstimmt, sp ist 13 und die beiden Instanzen von 0XD in der Codierung stimmen damit zusammen mit der unmittelbaren #8 überein.

Wenn Sie sich LDR (literal) ansehen, ist die Codierung 0x4800 mit einem Register und sofort. Diese Anweisung, wie sie dokumentiert ist, belastet den PC relativ, also ist der PC impliziert. Ebenso ist dies eine 32-Bit-Last. Wenn wir also von einer 32-Bit-Ausrichtung ausgehen, ist der Offset 0x34 sinnvoll 110100, da wir 32-Bit-Ausrichtung haben, brauchen wir die unteren beiden Bits nicht, die sie Anweisungsraum verbrennen, also 1101, was ein 0x0D ist, das 0x490D als Codierung ergibt.

Es steht in dem Dokument, das Sie sich ansehen, in Ordnung.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/CACCCHGF.html

490D: die '4' = 0100 und '9' = 1001, also sind die obersten fünf Bits 01001. Ein Blick in die Tabelle zeigt dies als "relative PC-Last". Die nächsten drei Bits sind 001 für 'Rd', das Zielregister. Der Operand ist 'D', was multipliziert mit 4 zum Zählen von Wörtern 0x34 ist.

F1AD0D08 ist ein bisschen seltsam. Jemand anderes kann das versuchen.

Ich dachte, ich erwähne zu diesem späten Zeitpunkt, dass die aktuelle Version des ARMv7m-Architektur-Referenzhandbuchs Kapitel 5 „The Thumb Instruction Set Encoding“ enthält, das zum Decodieren von CM4-Anweisungen hilfreich ist. Es ist immer noch ziemlich schwierig, weil der Befehlssatz im Wesentlichen wirklich hässlich und überhaupt nicht regelmäßig ist :-(

Aber für Ihren F1AD0D08 (1111 0001 1010 1101 0D 08):

Wenn die Bits [15:11] des zu decodierenden Halbworts einen der folgenden Werte annehmen, ist das Halbwort das erste Halbwort eines 32-Bit-Befehls: [gehe zu „32-Bit-Thumb-Befehlscodierung“ auf Seite n]

111 10 x1xxxxx -> Datenverarbeitung (Plain Binary Immediate) [Seite a5-141]

111 10 x1 01010 -> SUB (sofort) [Seite a7-402]

(das ist die Beschreibung der einzelnen Subtraktionsbefehle. Wir sehen, dass wir mit der Kodierung T4 übereinstimmen) 11110 i1 01010 1101 ... -> oops. "wenn Rn = 1101, siehe SUB (SP minus unmittelbar) [a7-406]

Jetzt sind wir also bei der Codierung von T3 von SUB (SP minus unmittelbar) 11110 i1 01010 1101 0 imm3 rd imm8

Wo wir einen 12-Bit-Sofortwert i:imm3:imm8 zusammenstellen, der in Ihrem Fall 8 ist, und Rd ist 0d (r13 oder SP.)

Ta Da!