ldr r0, #0x28
Que signifie cette instruction ldr
? Charge-t-il une chaîne à partir dun décalage? Comment puis-je trouver la chaîne / valeur réellement chargée?
Commentaires
Réponse
LDR charge une constante de 32 bits (LDRH (demi-mot): 16 bits, LDRB (octet): 8 bits) de la mémoire dans le registre cible spécifié (r0 dans votre exemple).
Comme les constantes 32 bits ne peuvent pas être encodées en opcodes 32 bits (ou 16 bits pour les instructions Thumb), lassembleur stocke la constante dans le segment de texte à proximité de linstruction de référencement, puis référence la valeur en utilisant ( généralement) adressage relatif au PC, cest-à-dire un décalage par rapport à r15.
Ainsi, ldr est en fait une pseudo instruction. Le code suivant
.code 32 main: ldr r0, =0x12345678 bx lr
est traduit par lassembleur en
00000000 <main>: 0: e51f0000 ldr r0, [pc, #-0] ; 8 <main+0x8> 4: e12fff1e bx lr 8: 12345678 .word 0x12345678
Comme vous pouvez voir, la constante référencée dans linstruction ldr originale est en fait stockée à ladresse 0x8 au lieu de dans linstruction elle-même. Linstruction ldr à ladresse 0 fait alors référence à cette valeur en utilisant ladressage relatif au PC. Le décalage vers le PC est de 0 (au lieu de 8), puisque la valeur réelle du PC est toujours ladresse de linstruction actuelle + 8 – cest un effet du premier pipeline de processeur ARM qui doit être préservé pour la compatibilité.
Réponse
Cela peut être simplement traduit en:
r0 = 0x28;
Dans lassemblage ARM, le #
marque les valeurs immédiates et le r0
, r1
, … sont des registres. Linstruction ldr
peut prendre les formes syntaxiques suivantes (la vôtre est la première ligne):
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
Réponse
ldr
sans =
est-ce que PC charge relative
Ceci est vrai pour les étiquettes et les nombres.
Mais vous utiliserez bien sûr rarement numéros directement dans votre assemblage. Peut-être avez-vous fourni un démontage sans étiquettes?
Les deux travaux suivants fonctionnent dans GNU GAS ARMv8. Avec un libellé:
ldr x0, pc_relative_ldr b 1f pc_relative_ldr: .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */
avec un décalage:
ldr x0, 0x8 b 1f .quad 0x123456789ABCDEF0 1: /* x0 == 0x123456789ABCDEF0 */
Les deux sont équivalents. Lassembleur convertit simplement létiquette en décalage correct pour vous.
GitHub en amont avec des assertions .
STR na pas dadressage relatif au PC comme LDR dans ARMv8, il vous suffit de calculer dabord ladresse dans les registres: https://stackoverflow.com/questions/28638981/howto-write-pc-relative-adressing-on-arm-asm/54480999#54480999
#0x28
et non=#0x28
?