jalr

RISC-V jalr 伪指令详解

汇编器伪指令

JALR 的省略操作数写法,常见形式默认链接到 ra、偏移为 0。它用于通过寄存器中的目标地址进行间接调用。

你写下的是
jalr rs / jalr offset(rs) / jalr rd, rs
常见真实展开
jalr ra, 0(rs) # or with offset: jalr ra, offset(rs) # or with explicit rd: jalr rd, 0(rs)

这条伪指令到底在帮你省什么

函数指针、PLT 跳板和寄存器间接调用经常使用 rd=ra 或 imm=0;伪指令让这些常见形式更简洁。

jalr 的核心作用是“间接调用并链接”。它是汇编器层面的简写;调试、审计或阅读机器码时,应回到页面列出的真实展开指令和相关重定位语义来判断行为。

官方语义核对重点

官方汇编手册把 jalr 作为汇编器层面的伪指令/别名处理,硬件执行的是展开后的真实指令序列。
真实语义以 JALR 等展开指令的 ISA 定义为准;本页不把 jalr 当作独立硬件 opcode。

工具链与链接器边界

jalr 的简写形式省略 rd 或 offset 时由汇编器补默认值;机器码语义仍以真实 JALR 为准。
间接调用、PLT 和函数指针场景中,最终目标由寄存器值和 12 位立即数决定,且 JALR 会清除目标 bit 0。

展开过程怎么理解

步骤 1
jalr rs 使用默认链接寄存器 ra、0 偏移和 rs 中的目标地址执行间接调用。
步骤 2
jalr offset(rs) 使用默认链接寄存器 ra 和给定偏移执行间接调用。
步骤 3
jalr rd, rs 使用显式链接寄存器 rd、0 偏移和 rs 中的目标地址执行间接调用。

在 objdump / 反汇编里可能看到什么

反汇编可能显示伪指令,也可能显示展开后的真实指令,取决于工具选项和上下文。

官方依据与阅读顺序

本页把伪指令当作汇编器层面的别名或宏来解释:先看它会展开成哪些真实指令,再回到官方 ISA 手册理解真实指令的行为。涉及 ABI、重定位或链接器松弛时,以 psABI 文档为准。

什么时候优先想到它

通过函数指针调用
跳转到寄存器保存的代码地址并保存返回地址
阅读 PLT、虚函数分发或间接调用序列

容易混淆 / 常见误区

JALR 目标地址会清除最低位 bit 0;不要把奇地址标签当作真实跳转目标
会覆盖链接寄存器 rd(默认 ra);需要保留旧返回地址时必须先保存
偏移是符号扩展 12 位立即数,不是任意寄存器偏移

常见问题

jalr 是真实 RISC-V 指令吗?

jalr 是汇编器伪指令或别名,不是单独硬件 opcode。页面中的“常见真实展开”列出官方展开,真实行为由展开后的 ISA 指令决定。

使用 jalr 时最容易误解什么?

JALR 目标地址会清除最低位 bit 0;不要把奇地址标签当作真实跳转目标