bx lr在ARM汇编语言中做了什么?

Tha*_*bid 20 assembly arm

我似乎无法理解bx lr的作用以及它与bl(标签)的区别.我知道bl(标签)将该函数的返回地址存储在链接寄存器中,但我不知道bx lr的作用.

MBy*_*ByD 23

bx代表分支和交换指令集这意味着根据要分支的地址的lsb(最低有效位),处理器将下一条指令视为ARM或拇指.

由于lr通常保存返回地址,这意味着这是函数的返回,如果lsb lr为1,它将以拇指的形式处理该地址的代码,否则,它将把它视为ARM.

  • @ user2177940第2部分:呼叫和呼叫返回.在ARMv7上,指令`bl nameOfFunction`通常用于调用子例程.`bl`指令将链接寄存器(`lr`)保存到下一条指令的地址,然后跳转到当前模式,然后跳转到所请求的子程序.当然,当该子程序希望返回时,它通过跳转到`lr`中的地址来知道返回的位置,并且因为`lr`也保存了调用函数的模式,所以也可以恢复.执行此工作的指令是`bx`. (6认同)
  • @ user2177940第1部分:模式切换.ARMv7 CPU以两种模式(称为ARM或Thumb)之一运行,这两种模式在指令编码方面不同(主要是"完整"但大的4字节指令与"受限制"但小的2字节指令).在呼叫时使用`bx/blx`**确定**切换到下一个模式,即跳转到的地址是偶数还是奇数(这会导致分别切换到ARM或Thumb模式). (5认同)
  • 我可以自己回答我的评论:“请注意,最低位实际上从未用作地址的一部分,因为所有指令都是 4 字节对齐(如 Arm)或 2 字节对齐(如 Thumb)。” (https://community.arm.com/processors/b/blog/posts/branch-and-call-sequences-explained) (4认同)
  • 你能不能简化一下这个解释,我对 ARM 架构的了解不是那么先进。 (3认同)
  • @IwillnotexistIdonotexist - 我认为如果你把评论作为答案,那就更好了. (2认同)

ATL*_*DEV 7

简而言之,一些 ARM 处理器可以执行 ARM 或 Thumb 指令集,并在代码密度和性能之间进行权衡。BX是一种特殊形式的分支指令,能够在两者之间切换1

它通过检测分支地址处的指令集(ARM 或 Thumb)来完成此操作。如果它与当前的不同,它会在分支到该地址之前将处理器切换到它。

.global _main                 ; our main code is ARM
   
_main:
    ADR   r2, .ThumbProg + 1  ; r2 now points to Thumb code address
    BX    r2                  ; BX detects its Thumb and switches
                              ; processor state to execute it
                              ; execute it.
 
Run Code Online (Sandbox Code Playgroud)

检测目标地址处的指令集并没有什么神奇或复杂的地方。

ARM 指令集是字对齐的,这意味着至少两个有效位 0 和 1 会被忽略,因为它们指的是地址的半字和字节部分。同样,Thumb 指令集是半字对齐的,这意味着位 0 被忽略,因为它引用地址的字节部分。

由于位 0 在这两种情况下都被忽略,因此可以利用它轻松确定地址处的代码是否包含 ARM 或 Thumb 代码。BX使用位 0 来:

  • 如果设置为 1,则执行 Thumb 状态下的分支地址
  • 如果设置为0,则执行ARM状态下的分支地址

1 ARM在指令名称中使用术语交换来表示更改执行状态。不幸的是,这会造成混乱。与火车从一组轨道切换到另一组轨道时一样,这两个指令集不会进行更多的交换。