我正在阅读MIPS bltzal
指令的文档,我看到了:
将返回地址链接放在GPR 31中。返回链接是 分支后面的第二条指令的地址,其中 程序调用后继续执行。一个18位有符号偏移量 (向左移位2位的16位偏移字段)被添加到地址 分支后面的指令(不是分支本身),in 分支延迟槽,形成PC相对有效目标地址。 如果GPR rs的内容小于零(符号位为1),则分支 到延迟指令后的有效目标地址 插槽已执行。
我解释这一点的方法是r31寄存器始终设置为延迟时隙之后的指令地址,即使未采用分支也是如此。另一个参考(https://imagination-technologies-cloudfront-assets.s3.amazonaws.com/documentation/MD00086-2B-MIPS32BIS-AFP-05.04.pdf)似乎证实了我的想法。我的理解是否正确?
我之所以问的是,我正在查看的ELF MIPS二进制文件在其入口点的开头就有以下两条指令:
bltzal r0,skip ; r0 is never lt 0, so fall into delay slot
nop ; but was r31 set or not?
skip:
lui +0x0FC1 ; add 0x0FC08628 to r31
addui r28,r28,-0x79D8
addu r28,r28,r31
显然意图取得skip
- 标记指令的指令地址并向其添加偏移量,大概是为了到达全局偏移表(GOT)。由于我们将r0
与0进行比较,因此永远不应该采用分支。如果未分配r31
寄存器,我们将调用来设置r31
,这会使bltzal
指令的使用完全冗余 - 为什么那么麻烦呢?