Wie funktioniert der ldr-Befehl auf ARM?

ldr r0, #0x28 

Was bedeutet die Anweisung ldr? Lädt es einen String von einem Offset? Wie finde ich die Zeichenfolge / den Wert, die / der tatsächlich geladen wird?

Kommentare

  • Sind Sie sicher, dass ' s #0x28 und nicht =#0x28?

Antwort

LDR lädt eine 32-Bit-Konstante (LDRH (Halbwort): 16 Bit, LDRB (Byte): 8 Bit) aus dem Speicher in das angegebene Zielregister (in Ihrem Beispiel r0).

Da 32-Bit-Konstanten nicht in 32-Bit-Opcodes (oder 16-Bit für Thumb-Anweisungen) codiert werden können, speichert der Assembler die Konstante im Textsegment nahe der Referenzierungsanweisung und verweist dann mit (auf den Wert) normalerweise) PC-relative Adressierung, dh ein gewisser Versatz von r15.

Somit ist ldr tatsächlich ein Pseudobefehl. Der folgende Code

 .code 32 main: ldr r0, =0x12345678 bx lr 

wird vom Assembler in

00000000 <main>: 0: e51f0000 ldr r0, [pc, #-0] ; 8 <main+0x8> 4: e12fff1e bx lr 8: 12345678 .word 0x12345678 

übersetzt siehe, die Konstante, auf die in der ursprünglichen ldr-Anweisung verwiesen wird, wird tatsächlich an der Adresse 0x8 anstatt in der Anweisung selbst gespeichert. Der ldr-Befehl an Adresse 0 verweist dann unter Verwendung der PC-relativen Adressierung auf diesen Wert. Der Offset zum PC ist 0 (anstelle von 8), da der tatsächliche PC-Wert immer die Adresse des aktuellen Befehls + 8 ist – dies ist ein Effekt der frühen ARM-Prozessor-Pipeline, die aus Kompatibilitätsgründen beibehalten werden muss.

Antwort

Dies kann einfach übersetzt werden in:

r0 = 0x28; 

In der ARM-Assembly markiert die # die unmittelbaren Werte und die r0, r1, … sind Register. Die Anweisung ldr kann die folgenden syntaktischen Formen annehmen (Ihre ist die erste Zeile):

LDR{type}{cond} Rt, [Rn {, #offset}] ; immediate offset LDR{type}{cond} Rt, [Rn, #offset]! ; pre-indexed LDR{type}{cond} Rt, [Rn], #offset ; post-indexed LDRD{cond} Rt, Rt2, [Rn {, #offset}] ; immediate offset, doubleword LDRD{cond} Rt, Rt2, [Rn, #offset]! ; pre-indexed, doubleword LDRD{cond} Rt, Rt2, [Rn], #offset ; post-indexed, doubleword 

Antwort

ldr ohne = lädt den PC relativ

Dies gilt sowohl für Beschriftungen als auch für Zahlen.

Aber Sie werden dies natürlich selten verwenden Nummern direkt in Ihrer Baugruppe. Vielleicht haben Sie eine Demontage ohne Etiketten bereitgestellt?

Beide der folgenden Arbeiten in GNU GAS ARMv8. Mit einer Bezeichnung:

 ldr x0, pc_relative_ldr b 1f pc_relative_ldr: .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

mit einem Versatz:

 ldr x0, 0x8 b 1f .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */ 

Beide sind gleichwertig. Der Assembler konvertiert zufällig die Beschriftung in den richtigen Offset für Sie.

GitHub stromaufwärts mit Zusicherungen .

STR hat keine PC-relative Adressierung wie LDR in ARMv8. Sie müssen lediglich zuerst die Adresse in Registern berechnen: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.