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
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.
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
#0x28
, a nie=#0x28
?