我想知道在ARM汇编中,有哪些指令可以用来跳转到存储在某个内存地址或标签中的地址。
例如,我们可以使用B LABEL来跳转到LABEL。但现在目的地只能在运行时确定,并且它存储在某个已知的内存位置,是否有类似于B [address]的东西?
谢谢!
是否有类似于B [address]的东西?
没有。首先将地址加载到寄存器中,然后使用 BX
跳转到该地址:
@ In this example, R0 points to the address to jump to
LDR R1, [R0]
BX R1
PC
中(虽然我不确定这是否适用于所有ARM架构,请查阅相关参考文档):@ In this example, R0 points to the address to jump to
LDR PC, [R0]
ARM架构的一个重要设计范式是只有很少的指令可以操作内存,这可能是一项较慢的操作:只有LDR
和STR
。因此,不存在从内存中执行B [label]
的情况。
对于寄存器部分的问题,回答这种问题的好方法是查看指令摘要部分,该部分将指令按类型分组。在ARMv7和ARMv8中有一个关于分支指令的摘要:
ARMv7 A4.3 "Branch instructions"
As mentioned at: https://dev59.com/Ao7ea4cB1Zd3GeqPDp9Q#32305904 , in ARMv7 you can use BX register
, and there is also a BLX register
which sets the return address for a function call.
From that table, we know which ones use register since only those can jump to "Any" address: those that use immediates have limited ranges as full addresses don't fit into the fixed 4 bytes per instruction encoding.
Another option in ARMv7 mentioned at: https://dev59.com/Ao7ea4cB1Zd3GeqPDp9Q#32305904 is to ldr
into the PC, since PC is just r15
:
ldr pc, [r0]
However, this is not possible anymore in ARMv8 where PC has a dedicated register. B1.2.1 "Registers in AArch64 state" says:
Software cannot write directly to the PC. It can only be updated on a branch, exception entry or exception return.
ARMv8 C3.1 "Branches, Exception generating, and System instructions"
In that section we learn about BLR
, BR
and RET
.
BR
is like BX
, but without X
since there is no thumb to worry about.
The docs then say that RET
is analogous to BR
, except that it:
x30
, which is where BL
puts the return addressTBB [Rn,Rm]
(所以寻址模式仅限于寄存器,当然不是标签)。ARM之所以没有其他内存间接跳转,是因为它是一台具有某种RISC设计的加载存储机器。而且它不能使用ldr r0,[label]
加载,除非在附近的PC相对位置或作为多个指令的伪指令。 - Peter Cordes
LDR R1, [R0]; MOV PC, R1
也是一种可能性。 - user1095108