Hvordan fungerer ldr-instruksjonen på ARM?

ldr r0, #0x28 

Hva instruerer ldr? Laster den en streng fra en offset? Hvordan kan jeg finne strengen / verdien som faktisk er lastet?

Kommentarer

  • er du sikker på at den ' s #0x28 og ikke =#0x28?

Svar

LDR laster en 32-bits konstant (LDRH (halvord): 16 bit, LDRB (byte): 8 bit) fra minnet i det spesifiserte målregisteret (r0 i ditt eksempel).

Siden 32-biters konstanter ikke kan kodes i 32-biters opkoder (eller 16-bits for tommelinstruksjoner), lagrer samleren konstanten i tekstsegmentet nær referanseinstruksjonen og refererer deretter verdien ved hjelp av vanligvis) PC-relativ adressering, dvs. noen forskyvning fra r15.

Dermed er ldr faktisk en pseudoinstruksjon. Følgende kode

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

oversettes av samleren til

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

Som du kan se, konstanten det refereres til i den opprinnelige ldr-instruksjonen er faktisk lagret på adressen 0x8 i stedet for i selve instruksjonen. Ldr-instruksjonen på adresse 0 refererer deretter til denne verdien ved hjelp av PC-relativ adressering. Forskyvningen til PC-en er 0 (i stedet for 8), siden den faktiske PC-verdien alltid er adressen til den gjeldende instruksjonen + 8 – dette er en effekt av den tidlige ARM-prosessorrørledningen som må bevares for kompatibilitet.

Svar

Dette kan enkelt oversettes til:

r0 = 0x28; 

I ARM-samling markerer # de umiddelbare verdiene og r0, r1, … er registre. Instruksjonen ldr kan ha følgende syntaktiske former (din er første linje):

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 

Svar

ldr uten = laster PC relativt

Dette gjelder både etiketter og tall.

Men du vil selvfølgelig sjelden bruke nummer direkte i forsamlingen. Kanskje du har gitt noen demontering uten etiketter?

Begge følgende fungerer i GNU GAS ARMv8. Med en etikett:

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

med en forskyvning:

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

Begge er likeverdige. Samleren konverterer bare etiketten til riktig forskyvning for deg.

GitHub oppstrøms med påstander .

STR har ikke PC-relativ adressering som LDR i ARMv8, du må bare beregne adressen i registre først: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *