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
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
#0x28
en niet=#0x28
?