jr
伪lyszt.net 更详细地介绍了 jr 和其他 RISC-V 指令。
描述
jr 跳转到存储在寄存器中的地址。这个名字代表 jump register。j 跳转到代码中写死的固定标签。jr 跳转到寄存器持有的任意地址,该地址由程序在运行时算出。它不保存返回地址。
jr 是下面这一行的伪指令,即丢弃返回地址的寄存器跳转(参见 jalr)。
jalr zero, rs, 0
跳转表是内存中的一个数组,保存着若干例程的地址,jr 会与它配合使用。要选择编号为 i 的例程,程序会计算它在表中的槽位,把存储在那里的地址加载到寄存器中,再用 jr 跳转到它。一次查找加一次跳转就能取代一长串比较(是 case 0、case 1、case 2 还是别的),无论有多少个分支都如此。密集的 switch 语句和解释器的内层循环分派就是这样做的。
RISC-V 手册把简单的无条件间接跳转编码为 rd 设为 x0 的 jalr。它指出,jalr 不像条件分支那样把其立即数视为 2 字节的倍数,并且 jalr 的大多数用法要么立即数为零,要么出现在 lui 或 auipc 之后。
从函数返回就是跳转到 ra 中的地址,所以 ret 只是换了个名字的 jr ra。这一组跳转指令的区别在于地址来自哪里,以及是否保存返回地址。
展开为
jalr zero, rs, 0
汇编器会将此伪指令替换为上面列出的真实指令或指令。
示例
la t0, target jr t0 # jump to the address held in t0
