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
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
#0x28
și nu=#0x28
?