Cum funcționează instrucțiunile ldr pe ARM?

ldr r0, #0x28 

Ce înseamnă instrucțiunea ldr? Încarcă un șir de la un offset? Cum pot găsi șirul / valoarea care este de fapt încărcat?

Comentarii

  • sunteți sigur că ' s #0x28 și nu =#0x28?

Răspuns

LDR încarcă o constantă de 32 de biți (LDRH (jumătate de cuvânt): 16 biți, LDRB (octet): 8 biți) din memorie în registrul țintă specificat (r0 în exemplul dvs.).

Deoarece constantele pe 32 de biți nu pot fi codate în coduri opționale pe 32 de biți (sau pe 16 biți pentru instrucțiunile Thumb), ansamblorul stochează constanta în segmentul de text aproape de instrucțiunea de referință și apoi face referință la valoarea utilizând ( de obicei) adresarea relativă la PC, adică o anumită compensare de la r15.

Astfel, ldr este de fapt o pseudoinstrucțiune. Următorul cod

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

este tradus de asamblor în

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

După cum puteți vezi, constanta la care se face referire în instrucțiunea ldr originală este de fapt stocată la adresa 0x8 în loc de instrucțiunea însăși. Instrucțiunea ldr la adresa 0 face apoi referire la această valoare utilizând adresarea relativă a PC-ului. Decalajul pentru PC este 0 (în loc de 8), deoarece valoarea reală a PC-ului este întotdeauna adresa instrucțiunii curente + 8 – acesta este un efect al conductei timpurii a procesorului ARM care trebuie păstrat pentru compatibilitate.

Răspuns

Acest lucru poate fi tradus pur și simplu în:

r0 = 0x28; 

În asamblarea ARM, # marchează valorile imediate și r0, r1, … sunt registre. Instrucțiunea ldr poate lua următoarele forme sintactice (a ta este prima linie):

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 

Răspuns

ldr fără = încărcările relative ale computerului

Acest lucru este valabil atât pentru etichete, cât și pentru numere.

Dar, desigur, veți folosi rar numerele direct în asamblarea dvs. Poate ați furnizat o dezasamblare fără etichete?

Ambele lucrări următoare în GNU GAS ARMv8. Cu o etichetă:

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

cu un offset:

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

Ambele sunt echivalente. Asamblatorul se întâmplă să transforme eticheta în offset-ul corect pentru dvs.

GitHub în amonte cu afirmații .

STR nu are adresare relativă la PC ca LDR în ARMv8, trebuie doar să calculați mai întâi adresa în registre: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *