ARM汇编跳转到寄存器或内存中的地址

5

我想知道在ARM汇编中,有哪些指令可以用来跳转到存储在某个内存地址或标签中的地址。

例如,我们可以使用B LABEL来跳转到LABEL。但现在目的地只能在运行时确定,并且它存储在某个已知的内存位置,是否有类似于B [address]的东西?

谢谢!

2个回答

7

是否有类似于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]

1
加载 PC 实际上在 ARM 指令集的所有版本中都得到支持,但 BX 不是。后一条指令直到 Thumb 指令集被添加到 ARM 架构中才存在。 - Ross Ridge
bx 指令从 ARMv4T 到现在基本上都得到了支持,包括 ARM7TDMI 到现在的所有版本,这是普通程序员所能看到的一切... - old_timer
LDR R1, [R0]; MOV PC, R1 也是一种可能性。 - user1095108
由于PC现在有专用寄存器,因此在ARMv8中不再可能使用“LDR PC,[R0]”。 - Ciro Santilli
@CiroSantilli 这很糟糕。这意味着没有办法在不破坏任何寄存器的情况下进行远程调用。 - Dan M.

5

ARM架构的一个重要设计范式是只有很少的指令可以操作内存,这可能是一项较慢的操作:只有LDRSTR。因此,不存在从内存中执行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.

    Minimal runnable example.

    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.

    Minimal runnable example.

    The docs then say that RET is analogous to BR, except that it:

    • gives a hint that this is supposed to represent a function return
    • the register is optional on the assembly, and defaults to x30, which is where BL puts the return address

1
你忘了提到Thumb-2模式TBB/TBH(表分支字节/半字),它索引一个PC相对偏移量的数组并跳转到那里。这是用于类似switch语句跳转表的东西。TBB [Rn,Rm](所以寻址模式仅限于寄存器,当然不是标签)。ARM之所以没有其他内存间接跳转,是因为它是一台具有某种RISC设计的加载存储机器。而且它不能使用ldr r0,[label]加载,除非在附近的PC相对位置或作为多个指令的伪指令。 - Peter Cordes
@PeterCordes 啊,谢谢,我不知道那个! - Ciro Santilli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接