Jak funguje instrukce ldr na ARM?

ldr r0, #0x28 

Co znamená thw ldr instrukce? Načte řetězec z nějakého offsetu? Jak najdu skutečně načtený řetězec / hodnotu?

Komentáře

  • jste si jisti, že ' s #0x28 a ne =#0x28?

odpověď

LDR načte 32bitovou konstantu (LDRH (půl slova): 16 bitů, LDRB (bajt): 8 bitů) z paměti do zadaného cílového registru (ve vašem příkladu r0).

Vzhledem k tomu, že 32bitové konstanty nelze zakódovat do 32bitových operačních kódů (nebo 16bitových pro instrukce Palec), assembler uloží konstantu do textového segmentu poblíž odkazovací instrukce a poté odkazuje na hodnotu pomocí ( obvykle) PC-relativní adresování, tj. určité posunutí od r15.

Ldr je tedy ve skutečnosti pseudo instrukcí. Následující kód

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

je asemblerem přeložen do

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

Jak můžete viz, konstanta odkazovaná v původní instrukci ldr je ve skutečnosti uložena na adrese 0x8 místo v samotné instrukci. Instrukce ldr na adrese 0 poté odkazuje na tuto hodnotu pomocí PC-relativního adresování. Ofset k PC je 0 (místo 8), protože skutečná hodnota PC je vždy adresa aktuální instrukce + 8 – to je účinek raného kanálu procesoru ARM, který je nutné kvůli kompatibilitě zachovat.

Odpověď

Lze to jednoduše přeložit do:

r0 = 0x28; 

V sestavě ARM # označuje okamžité hodnoty a r0, r1, … jsou registry. Instrukce ldr může mít následující syntaktické formy (vaše je první řádek):

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 

Odpovědět

ldr bez = načítá relativní PC

To platí jak pro štítky, tak pro čísla.

Ale samozřejmě je zřídka použijete čísla přímo ve vaší sestavě. Možná jste provedli demontáž bez štítků?

Obě následující práce fungují v GNU GAS ARMv8. Se štítkem:

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

s posunem:

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

Oba jsou rovnocenné. Assembler právě provede převod štítku na správný offset pro vás.

GitHub proti proudu s tvrzeními .

STR nemá v PCM relativní adresování jako LDR v ARMv8, stačí nejprve vypočítat adresu do registrů: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *