start MOV r0,#10
ADRL r4,start + 60000 ; => ADD r4,pc,#0xe800
; ADD r4,r4,#0x254
我看不懂代码中的注释。因为 60000 是 0xea60。我认为r4应该是pc + #0xea60。 但注释说(实际上,发出的指令)r4 变为 pc + #0xe800 + #0x254 = pc + 0xea54。 (不是#ea60)。为什么少了12个?
这些是arm(即arm32)指令,即使您的标题和标签最初说的是arm64。 请注意,寄存器是
r0
等,而不是 x0
或 w0
。
在处于非 Thumb (A32) 状态的 32 位 ARM 上,PC 读取当前指令的地址加 8。(这在我的 Armv8- 副本中的架构参考手册 E.1.2.3 中进行了解释)一个版本。)
因此,如果
start
位于地址0x0,则ADD r4,pc,#0xe800
指令位于地址0x4,因此pc
将被读取为0xc
。 因此 ADD r4,pc,#0xe800
将使用 r4
加载 0xe80c
。 然后添加 0x254
将使 r4
包含所需的 0xea60
。
arm64 不同。 在那里,PC 不能作为通用寄存器进行访问,因此您不能直接移至或移出它,但作用于它的像
ADR
这样的指令确实将其视为指向当前指令(没有 8 字节)偏移)。