ret伪

ret

伪
RISC-V 汇编 参考

lyszt.net 更详细地介绍了 ret 和其他 RISC-V 指令。

描述

ret 从函数返回,将控制权交还给调用者。call 期望如此。当函数被调用时,调用者将返回地址放入 ra 寄存器(参见 call 和 jal),而 ret 跳转到该地址,从原始调用之后继续执行。它是一条跳转到 ra 的伪指令。

ret 仅在 ra 仍保存正确地址时有效。在不调用其他任何东西的函数中,从入口到出口之间没有任何东西会改变 ra。函数内部的 call 会用新的返回地址覆盖 ra,抹掉函数所需的地址。调用其他函数的函数会在入口保存其 ra,并在 ret 之前恢复它。如果不恢复,函数会返回到错误的位置,程序会跳转到无关代码或永远循环。

按照约定,函数在返回前将结果放入 a0 寄存器,调用者在那里读取它。

RISC-V 手册指出,标准调用约定中的过程返回被编码为 rd=x0、rs1=x1、立即数为 0 的 jalr。它跳转到 x1 中的地址,并且不写入链接地址,因为 x0 会丢弃它。手册还补充说,处理器使用 jal 和 jalr 中的寄存器编号作为预测函数返回的提示,这是标准约定将返回地址保留在 x1 中的原因之一。

示例是最简单的完整函数。square 将其参数与自身相乘,ret 返回结果。它不调用其他任何东西,因此不保存也不恢复任何内容。在模拟器中运行它,可以看到控制权跳回调用者。

展开为

jalr zero, ra, 0

汇编器会将此伪指令替换为上面列出的真实指令或指令。

示例

square:
  mul a0, a0, a0
  ret              # return to the caller