首页/指令库/CSR读写交换
CSRRW

RISC-V CSRRW 指令详解

指令手册I-type

原子地读取 CSR 旧值到 rd,并把 rs1 的值写入同一 CSR;rd=x0 时抑制 CSR 读取

指令语法

csrrw rd, csr, rs1
操作数说明
目标寄存器 rd:存放运算结果的通用寄存器。
源寄存器 rs1:第一个操作数所在的寄存器。
立即数 imm:12 位有符号立即数,符号扩展后与 rs1 进行运算。
ZicsrCSR操作系统

指令行为说明

CSRRW 是 Zicsr 的 CSR 原子读/写指令:在一条指令内把目标 CSR 的旧值零扩展到 XLEN 后写入 rd,并把 rs1 的值写入该 CSR。若 rd=x0,指令不读取 CSR,也不产生 CSR 读副作用,但写操作仍按 rs1 执行。CSR 地址字段为 12 位;对不存在、权限不足或只读 CSR 的非法写入会产生 illegal-instruction 异常。

CSRRW 指令解析与执行动画

展示 Zicsr CSR 读-改-写的 ISA 可见流程:解析 SYSTEM 编码、读取 CSR、按写/置位/清位语义计算,再更新 rd 与 CSR。

rd
csr
rs1
csrrw
,
,
执行环境
执行环境

CSR 名称/地址属于指令语法;旧 CSR 值和 rs1 示例值属于执行上下文。动画不赋予示例 CSR 任何具体平台字段含义。

31..20
19..15
14..12
11..7
6..0
011111000000
csr[11:0]
00110
rs1
001
funct3
00101
rd
1110011
opcode
执行数据路径
instruction
0x7C0312F3
opcode
1110011 -> SYSTEM
funct3
001 -> CSRRW
operands
rd=t0(x5), csr=0x7C0, rs1=t1(x6)
CSR read
0x7C0 -> 0x0000000A
rs1 source
t1(x6) -> 0x00000003
CSR update
CSR = 0x00000003
rd update
t0(x5) = 0x0000000A
当前步骤

拿到 CSRRW 的 32-bit SYSTEM 编码

CSRRW 是 Zicsr 定义的 I-type SYSTEM 指令,CSR 地址位于 bits 31..20。

encoding: 0x7C0312F3
syntax : csrrw t0(x5), 0x7C0, t1(x6)
result : t0(x5) = 0x0000000A; CSR = 0x00000003
CSR 位级结果
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
old CSR
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
write value
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
write
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

位级视图显示当前 XLEN 的 CSR 值计算。

该动画只展示 Zicsr 定义的 ISA 可见 CSR 读写、副作用抑制和位掩码语义;不模拟具体 CSR 字段含义、异常处理器、流水线或时序。

快速理解与检索要点

CSRRW 把 CSR 旧值送到 rd,同时把 rs1 写入 CSR。rd=x0 是写-only CSR 操作:不读 CSR、不触发读副作用,但仍写 CSR。

CSR 地址字段为 12 位,位于 I-type SYSTEM 编码的 csr[11:0]。
rd=x0 时 CSRRW/CSRRWI 不读取 CSR,也不产生读副作用。
CSRRW 的源是 rs1;rs1=x0 表示写入零,不表示不写。
CSR 地址高两位为 11 的只读 CSR 不能通过会写 CSR 的形式写入;这类写入会触发 illegal-instruction,CSRRS/CSRRC 的零源只读特例除外。

常见使用场景

系统与特权

结合 «csrrw x5, mepc, x6 # x5 = old mepc; mepc = x6» 等实际代码理解该场景。

原子与同步

结合 «csrrw x5, mepc, x6 # x5 = old mepc; mepc = x6» 等实际代码理解该场景。

使用前检查清单

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

容易混淆 / 常见误区

rd=x0 只抑制 CSR 读取和读副作用;不会把 CSRRW 变成不写 CSR 的指令。
rs1=x0 会向 CSR 写入零值;这不同于 CSRRS/CSRRC 的只读特例。
CSR 地址为 12 位,但目标 CSR 是否存在、是否可写、当前权限是否足够仍由架构规则约束。

常见问题

CSR 指令里的 atomic 是内存原子吗?

不是。Zicsr 里的 atomic 指 CSR 读和写在同一条 CSR 指令中完成,不是对内存地址执行 AMO。

rd=x0 和 rs1/uimm=0 的效果一样吗?

不一样。rd=x0 只在 CSRRW/CSRRWI 中抑制 CSR 读取;rs1=x0 或 uimm=0 只在 CSRRS/CSRRC 及其立即数形式中抑制 CSR 写入。