Come funziona listruzione ldr su ARM?

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

  • sei sicuro che sia ' s #0x28 e non =#0x28?

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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *