Jak działa instrukcja ldr na ARM?

ldr r0, #0x28 

Jaka jest instrukcja thw ldr? Czy ładuje ciąg z jakiegoś przesunięcia? Jak mogę znaleźć ciąg / wartość, która jest rzeczywiście załadowana?

Komentarze

  • czy na pewno ' s #0x28, a nie =#0x28?

Odpowiedź

LDR ładuje 32-bitową stałą (LDRH (półsłowo): 16 bitów, LDRB (bajt): 8 bitów) z pamięci do określonego rejestru docelowego (w przykładzie r0).

Ponieważ 32-bitowe stałe nie mogą być zakodowane w 32-bitowych kodach operacyjnych (lub 16-bitowych w przypadku instrukcji Thumb), asembler przechowuje stałą w segmencie tekstowym blisko instrukcji odwołującej się, a następnie odwołuje się do wartości za pomocą zazwyczaj) adresowanie zależne od komputera, tj. pewne przesunięcie względem r15.

Zatem ldr jest w rzeczywistości pseudoinstrukcją. Poniższy kod

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

jest tłumaczony przez asembler na

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

Jak możesz Zobacz, stała, do której odwołuje się oryginalna instrukcja ldr, jest w rzeczywistości przechowywana pod adresem 0x8 zamiast w samej instrukcji. Instrukcja ldr pod adresem 0 odwołuje się następnie do tej wartości, używając adresowania zależnego od komputera. Przesunięcie względem komputera wynosi 0 (zamiast 8), ponieważ rzeczywistą wartością PC jest zawsze adres bieżącej instrukcji + 8 – jest to efekt wczesnego potoku procesora ARM, który musi zostać zachowany w celu zapewnienia kompatybilności.

Odpowiedź

Można to po prostu przetłumaczyć na:

r0 = 0x28; 

W zestawie ARM # oznacza bezpośrednie wartości, a r0, r1, … to rejestry. Instrukcja ldr może przybierać następujące formy składniowe (Twoja jest pierwsza linia):

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 

Odpowiedz

ldr bez = czy obciążenia względne na PC

Dotyczy to zarówno etykiet, jak i liczb.

Ale oczywiście rzadko będziesz używać numery bezpośrednio w swoim zespole. Może zapewniliście demontaż bez etykiet?

Oba poniższe elementy działają w GNU GAS ARMv8. Z etykietą:

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

z przesunięciem:

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

Oba są równoważne. Asembler po prostu przekształca etykietę we właściwe przesunięcie dla Ciebie.

GitHub upstream z asercjami .

STR nie ma adresowania zależnego od komputera, takiego jak LDR w ARMv8, wystarczy najpierw obliczyć adres w rejestrach: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *