【问题标题】:ARMv7: Is there a way to branch with link from a register?ARMv7:有没有办法通过寄存器的链接进行分支?
【发布时间】:2021-05-02 14:25:57
【问题描述】:

在 ARMv7 中,我知道有 bl 指令分支到一个地址并更新链接寄存器以指向它之后的指令。我也知道可以使用bl跳转到直接引用的标签,如下:

bl example_label
mov r5, 0
example_label:
mov r5, 111
@ blah blah blah

但是,当example_label 引用的地址在寄存器中时,比如说r0,我在执行以下操作时会出错:

bl r0
mov r5, 0
example_label:
mov r5, 111
@ blah blah blah

有没有办法可以使用寄存器执行bl 指令?我必须使用其他方法吗?还是完全不可能?

提前致谢!

编辑:

根据tum_的要求更新了代码sn-p

push lr  # you need to store this
ldr r0, =example_label
blx r0  # overwrites existing lr.
mov r5, 0
pop pc   # return to saved caller and don't execute example label again...
example_label:
mov r5, 111
@ blah blah blah
bx lr # not blah blah, you need to return control to caller.

【问题讨论】:

  • 一如既往地询问编译器。在这种情况下,编译一个带有函数指针 arg 的函数(并且不能进行尾调用优化)。 godbolt.org/z/d1ddG4s4h 使用 blx r0 显示它。
  • 您能否更详细地解释一下为什么您认为更新后的代码不起作用?它应该,所以你的测试可能还有其他问题。 minimal reproducible example 最好。您在 cmets 中谈论 Default_handler 但您向我们展示的代码中没有这样的东西,所以我们无法真正理解。
  • 您需要bx lrEND 处将“example_label”设为子例程。但是当返回mov r5, #0 时,您将再次运行“example_label”。您需要控制 sn-ps 末端的流量。 blx r0 是正确的。 “x”是处理拇指互通,这是 ARMv7 的历史包袱。 'Thumb2' 使'interworking' 过时了......但它是跳转到寄存器的方式并允许纯 32 位 ARM 模式,这是为了向后兼容。
  • 当你可以只使用 bl example_label 时,为什么还要使用 ldr r0、blx r0?
  • 你需要知道函数是拇指代码还是手臂代码顺便说一句,并使用适当的地址。所有这些都由 arm 在 armv7-a(或 armv7-m 取决于您所谈论的那个)的架构参考手册中记录。请张贴您感到困惑的段落。

标签: assembly arm


【解决方案1】:

【讨论】:

  • 刚试过。紧随其后的指令 (mov r5, 0) 最终将我直接带到了 Default_Handler 标签,该标签只有 nopbl Default_Handler
  • blx 是在寄存器中按地址进行分支的正确方法。您确定r0 寄存器包含有效地址吗?顺便说一句,mov r5, 0 不访问内存,也不能抛出异常。
  • 我在blx r0 之前做了ldr r0, =example_label,在我的第一条评论中我应该说mov r5, 111 而不是mov r5, 0。对于那个很抱歉。无论哪种方式,我仍然会被扔到默认处理程序
  • @Kookie 请通过editing您的问题向我们展示完整的代码片段。
  • @tum_ 没问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-24
  • 1970-01-01
  • 2018-08-04
  • 1970-01-01
  • 2012-05-07
相关资源
最近更新 更多