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

RISC-V JALR 指令详解

指令手册I-type

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

指令语法

jalr rd, offset(rs1)
操作数说明
目标寄存器 rd:存放运算结果的通用寄存器。
源寄存器 rs1:第一个操作数所在的寄存器。
立即数 imm:12 位有符号立即数,符号扩展后与 rs1 进行运算。
RV32I控制转移跳转

指令编码

31..20
imm[11:0]
19..15
rs1
14..12
funct3
11..7
rd
6..0
opcode

JALR 使用 opcode 1100111(0x67)、funct3 000。rs1 字段选择源寄存器,12 位立即数提供第二操作数,rd 选择目标寄存器。

格式: I-type
opcode: 1100111 (0x67)
funct3: 000 (0x0)

指令行为说明

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

快速理解与检索要点

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

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

官方规范要点

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

常见使用场景

函数调用与返回

使用 jal ra, label 或 jalr ra, rs, imm。

分支与跳转

结合 «jalr x1, 0(x5) # jump to x5, x1 = pc+4» 等实际代码理解该场景。

使用前检查清单

语法检查
  • 确认当前指令格式为 I-type。
  • 确认操作数排列顺序与示例一致。
语义检查
  • 确认目标寄存器用途和调用约定兼容。
  • 确认该指令不是伪指令展开后的底层形式。

容易混淆 / 常见误区

目标地址 bit 0 会被清零;这不保证 4 字节对齐,未对齐异常仍取决于目标地址和 IALIGN
返回地址栈(RAS)的行为由 rd 和 rs1 的组合隐式控制
直接 JALR x0,rs1,0 等价于 JR 伪指令(不保存返回地址)

常见问题

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

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

RET 通常展开成什么?

常见返回形式是 jalr x0, 0(ra),也就是不写返回地址、跳转到 ra 指向的位置。