gpt4 book ai didi

assembly - 在 ARM 汇编中将 LR 推到 BL 指令之前

转载 作者:行者123 更新时间:2023-12-02 08:01:50 24 4
gpt4 key购买 nike

我试图更好地理解为什么在调用 BL 指令之前推送 LR。我知道 BL 指令将分支到另一个子例程,然后将 PC 恢复到 BL 调用之后的指令地址,但为什么 LRBL 被称为?我已经编写了下面用于阶乘计算的完整递归代码以提供上下文。 a和b都是用pseudo编写的变量。

LDR   RO, a
PUSH (LR)
BL factorial
STR R0, b
POP (LR)

factorial:
CMP RO, #0
MOVEQ R0, #1
MOVEQ PC, LR
MOV R3, R0
SUB R0, R0, #1
PUSH (R3, LR)
BL factorial
MUL R0, R3, R0
POP (R3, LR)
MOV PC, LR

我明白这个程序应该如何流动,但我对堆栈中存储的地址感到困惑。显然,您想要的地址“STR R0, b”指令将在第一次分支调用后放入堆栈,但如果 LRBL调用?

最佳答案

but why is the LR pushed before the BL is called?

在这里您可以看到递归的成本。从更高级别的编码角度来看,递归看起来很简单。状态由编译器存储在堆栈帧中。只有一个 LR 寄存器适合叶函数。然而,如果你有一个扩展的调用链,“A调用B调用C调用D”,那么当使用LR在“D”中执行时,必须存储“A,B和C”的返回地址> 返回“C”。对于递归来说,“A、B、C、D”都是相同的。

参见:ARM Link register and frame pointer了解更多。

我相信看到这些额外的说明是有启发性的。通常可以形成循环而不是递归,并且线性流程将执行得更快,并且使用相同数量的变量和更少的代码。堆栈帧和操作对使用高级语言的程序员是隐藏的。

由于“尾递归”,不需要框架也是很常见的。实际上,只有第一次调用阶乘需要保存返回地址,而不是 bl ,一个简单的 b 就可以了。

关于assembly - 在 ARM 汇编中将 LR 推到 BL 指令之前,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53625807/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com