Hoe werkt de ldr-instructie op ARM?

ldr r0, #0x28 

Wat betekent de ldr instructie? Laadt het een string vanaf een bepaalde offset? Hoe kan ik de string / waarde vinden die daadwerkelijk is geladen?

Opmerkingen

  • weet je zeker dat deze ' s #0x28 en niet =#0x28?

Antwoord

LDR laadt een 32-bits constante (LDRH (halfwoord): 16 bit, LDRB (byte): 8 bit) uit het geheugen in het opgegeven doelregister (r0 in uw voorbeeld).

Aangezien 32-bits constanten niet kunnen worden gecodeerd in 32-bits opcodes (of 16-bits voor Thumb-instructies), slaat de assembler de constante op in het tekstsegment dicht bij de verwijzende instructie en verwijst vervolgens naar de waarde met ( meestal) PC-relatieve adressering, dwz een afwijking van r15.

Dus ldr is in feite een pseudo-instructie. De volgende code

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

wordt door de assembler vertaald in

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

Zoals je kunt zie, de constante waarnaar wordt verwezen in de originele ldr-instructie wordt in feite opgeslagen op adres 0x8 in plaats van in de instructie zelf. De ldr-instructie op adres 0 verwijst vervolgens naar deze waarde met behulp van pc-relatieve adressering. De offset naar de pc is 0 (in plaats van 8), aangezien de werkelijke pc-waarde altijd het adres is van de huidige instructie + 8 – dit is een effect van de vroege ARM-processorpijplijn die moet worden behouden voor compatibiliteit.

Antwoord

Dit kan eenvoudig worden vertaald in:

r0 = 0x28; 

In ARM-assembly markeert de # de onmiddellijke waarden en de r0, r1, … zijn registers. De ldr instructie kan de volgende syntactische vormen aannemen (jouwe is de eerste regel):

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 

Antwoord

ldr zonder = doet pc relatieve belastingen

Dit geldt voor zowel labels als getallen.

Maar je zult natuurlijk zelden gebruiken nummers direct in uw montage. Misschien heb je voor wat demontage gezorgd zonder labels?

Beide volgende werken in GNU GAS ARMv8. Met een label:

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

met een offset:

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

Beide zijn equivalent. De assembler zet toevallig het label om in de juiste offset voor jou.

GitHub stroomopwaarts met beweringen .

STR heeft geen pc-relatieve adressering zoals LDR in ARMv8, je hoeft alleen het adres eerst in de registers te berekenen: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *