首页/指令库/寄存器跳转并链接
JALR

RISC-V JALR 指令详解

指令手册I-type

将rs1与12位有符号立即数相加(结果最低位清零)作为目标地址跳转,同时将返回地址写入rd

指令语法

jalr rd, offset(rs1)
操作数说明
rd:成功跳转时接收旧 PC+4;rd=x0 时写回被丢弃。
rs1:提供跳转基址,使用写回之前的源值。
imm:-2048 到 2047 的有符号字节偏移;rs1+符号扩展的 imm 按 XLEN 截断,再清除 bit 0。目标还须满足当前 IALIGN。
RV32IRV64I控制转移跳转

指令行为说明

JALR指令采用I型格式(opcode=1100111, funct3=000)。目标地址由rs1与12位有符号立即数相加后,最低位强制清零得到。同时将返回地址(PC+4)写入寄存器rd。rd=x0 时执行不保存返回地址的间接跳转;官方手册将普通无条件间接跳转的 JR 伪指令描述为 rd=x0 的 JALR。当rd=x0且rs1=x1且imm=0时即为函数返回(伪指令RET)。结果最低位清零的设计既简化硬件,也允许函数指针最低位存储辅助信息。rd和rs1为x1/x5时的组合为返回地址栈(RAS)提供隐式预测提示。

JALR 指令解析与执行动画

从机器码字段解析开始,依次展示操作数读取、该指令专属语义计算和 ISA 可见状态更新。

rd
imm
rs1
jalr
,
(
)
执行环境

本例使用固定寄存器初值和初始 PC=0x2000;取指成功,没有异步中断或额外扩展检查。异常分支只显示普通提交停止,陷入后的 PC 和处理程序状态由 EEI 决定。

t0(x5)
0x00003001
PC
0x00002000
31..20
19..15
14..12
11..7
6..0
000000000000
imm[11:0]
00101
rs1
000
funct3
00001
rd
1100111
opcode
执行数据路径
instruction
0x000280E7
opcode
1100111 -> JALR
funct3
000 -> JALR
rd / rs1 / pc
ra(x1) / t0(x5)=0x00003001 / 0x00002000
imm[11:0]
000000000000 -> 0
target/link
尚未计算
PC / link
ra(x1) = 0x00002004; pc = 0x00002000
当前步骤

概念步骤:拿到 32-bit 指令编码

机器码按当前指令格式切成字段,动画从 encoding/decode 开始。

encoding: 0x000280E7
syntax : jalr x1, 0(x5)
待提交结果: 尚未计算
当前架构状态
ra(x1) = 0x00002004; pc = 0x00002000

该动画展示 ISA 可见的解码和状态变化,不表示任何特定 CPU 的流水线、缓存、预测或时序实现。

快速理解与检索要点

JALR 是寄存器间接跳转并链接:目标地址由 rs1 加符号扩展的 12 位立即数得到,并在跳转前把最低位清零,同时把 pc+4 写入 rd。

JALR 的立即数不是按 2 字节缩放,而是普通 12 位有符号字节偏移。
清零最低位允许函数指针低位携带辅助信息,也简化硬件。

官方规范要点

以下要点按 RISC-V Unprivileged ISA 手册核准,用于补充操作语义、立即数范围和边界行为。

常见使用场景

函数调用与返回

RV32I/RV64I、IALIGN=32 示例:PC=0x2000、ra=0x3001 时,jalr x0, 0(ra) 成功跳到 0x3000;x0 保持为 0。

分支与跳转

RV32I/RV64I、IALIGN=32 示例:PC=0x2000、ra=0x3001 时,jalr x0, 0(ra) 成功跳到 0x3000;x0 保持为 0。

使用前检查清单

语法检查
  • 寄存器操作数选择 x0 到 x31;ABI 寄存器名是这些寄存器的别名。
  • 12 位有符号立即数的可编码范围为 -2048 到 2047;该范围包括两个端点。
语义检查
  • 目标为 rs1+符号扩展的字节偏移,按 XLEN 截断后清除 bit 0;目标还须满足 IALIGN。
  • 成功跳转时 rd 接收旧 PC+4,写入 x0 被丢弃;rs1 使用写回前的源值。

容易混淆 / 常见误区

目标地址 bit 0 会被清零;这不保证 4 字节对齐,未对齐异常仍取决于目标地址和 IALIGN
rd 和 rs1 的 x1/x5 组合提供隐式 RAS 预测提示,不保证具体预测行为或性能
直接 JALR x0,rs1,0 等价于 JR 伪指令(不保存返回地址)

常见问题

为什么 JALR 会清零目标地址最低位?

官方手册说明这样可简化硬件,并允许函数指针最低位存储辅助信息。

RET 通常展开成什么?

标准返回形式是 jalr x0, 0(ra)。目标为原 ra 的最低位清零后的地址(ra & ~1);链接地址写入 x0 被丢弃。IALIGN=32 时目标还必须是 4 的倍数,否则引发指令地址未对齐异常。