ldr r0, #0x28
Che cosa sono le istruzioni ldr
? Carica una stringa da qualche offset? Come posso trovare la stringa / il valore effettivamente caricato?
Commenti
Risposta
LDR carica una costante a 32 bit (LDRH (halfword): 16 bit, LDRB (byte): 8 bit) dalla memoria nel registro di destinazione specificato (r0 nel tuo esempio).
Poiché le costanti a 32 bit non possono essere codificate in codici operativi a 32 bit (o 16 bit per le istruzioni Thumb), lassemblatore memorizza la costante nel segmento di testo vicino allistruzione di riferimento e quindi fa riferimento al valore utilizzando ( di solito) indirizzamento relativo al PC, cioè un certo offset da r15.
Quindi, ldr è in effetti una pseudo istruzione. Il codice seguente
.code 32 main: ldr r0, =0x12345678 bx lr
viene tradotto dallassemblatore in
00000000 <main>: 0: e51f0000 ldr r0, [pc, #-0] ; 8 <main+0x8> 4: e12fff1e bx lr 8: 12345678 .word 0x12345678
Come puoi vedete, la costante referenziata nellistruzione ldr originale è infatti memorizzata allindirizzo 0x8 invece che nellistruzione stessa. Listruzione ldr allindirizzo 0 fa quindi riferimento a questo valore utilizzando lindirizzamento relativo al PC. Loffset al PC è 0 (invece di 8), poiché il valore effettivo del PC è sempre lindirizzo dellistruzione corrente + 8 – questo è un effetto della pipeline dei primi processori ARM che deve essere preservata per compatibilità.
Risposta
Questo può essere semplicemente tradotto in:
r0 = 0x28;
Nellassembly ARM, #
contrassegna i valori immediati e r0
, r1
, … sono registri. Listruzione ldr
può assumere le seguenti forme sintattiche (la tua è la prima riga):
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
Risposta
ldr
senza =
esegue carichi relativi al PC
Questo vale sia per le etichette che per i numeri.
Ma ovviamente lo userai raramente numeri direttamente nel tuo assieme. Forse hai fornito un po di disassemblaggio senza etichette?
Entrambi i seguenti funzionano in GNU GAS ARMv8. Con unetichetta:
ldr x0, pc_relative_ldr b 1f pc_relative_ldr: .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */
con un offset:
ldr x0, 0x8 b 1f .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */
Entrambi sono equivalenti. Lassembler converte letichetta nelloffset corretto per te.
GitHub a monte con asserzioni .
STR non ha lindirizzamento relativo al PC come LDR in ARMv8, devi solo calcolare prima lindirizzo nei registri: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999
#0x28
e non=#0x28
?