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

RISC-V CSRRW 指令详解

指令手册I-type

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

指令语法

csrrw rd, csr, rs1
操作数说明
RV32/RV64 Zicsr 2.0;32 位 SYSTEM 编码,opcode=1110011、funct3=001。
rd=[11:7] 选择整数寄存器;csr=[31:20] 是 12 位地址,不是有符号算术立即数;rs1=[19:15] 选择整数源寄存器。
把源初值写入 CSR;rd≠x0 时将旧 CSR 值零扩展到 XLEN 写 rd。rd=x0 抑制 CSR 读取及读副作用,但仍尝试写。
rs1=x0 尝试写入零;rd 与 rs1 重叠时仍使用旧 rs1 值。
CSR 必须已实现且访问获准;只读 CSR 写尝试触发 illegal-instruction。具体字段的可写性、读回值和副作用规则仍适用。
ZicsrCSR操作系统

指令行为说明

CSRRW 是 Zicsr 的 CSR 原子读/写指令:在一条指令内把目标 CSR 的旧值零扩展到 XLEN 后写入 rd,并把 rs1 的值写入该 CSR。若 rd=x0,指令不读取 CSR,也不产生 CSR 读副作用,但写操作仍按 rs1 执行。CSR 地址字段为 12 位。

CSRRW 指令解析与执行动画

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

rd
csr
rs1
csrrw
,
,
执行环境

假设 CSR 已实现且访问获准,示例位为普通可写位。只读 CSR 写尝试显示异常,不提交结果。

CSR 名称/地址属于指令语法;旧 CSR 值和 rs1 示例值属于执行上下文。动画按显示位可写来计算示例结果;实际 CSR 的可写位、读回值和字段副作用须遵循该 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 表示写入零,不表示不写。
CSRRW 总会尝试写 CSR;具体 CSR 的可写位、读回值和字段副作用由该 CSR 的规范决定。

常见使用场景

系统与特权

假设 0x7c0 自定义 CSR 已实现、访问获准、示例位均为普通可写位,旧 CSR=0xa:csrrw x5,0x7c0,x6 → x5=0xa, CSR=3 (x6=3)

CSR 访问

假设 0x7c0 自定义 CSR 已实现、访问获准、示例位均为普通可写位,旧 CSR=0xa:csrrw x5,0x7c0,x6 → x5=0xa, CSR=3 (x6=3)

使用前检查清单

语法检查
  • RV32/RV64 Zicsr 2.0;32 位 SYSTEM 编码,opcode=1110011、funct3=001。
  • rd=[11:7] 选择整数寄存器;csr=[31:20] 是 12 位地址,不是有符号算术立即数;rs1=[19:15] 选择整数源寄存器。
语义检查
  • 把源初值写入 CSR;rd≠x0 时将旧 CSR 值零扩展到 XLEN 写 rd。rd=x0 抑制 CSR 读取及读副作用,但仍尝试写。
  • rs1=x0 尝试写入零;rd 与 rs1 重叠时仍使用旧 rs1 值。
  • CSR 必须已实现且访问获准;只读 CSR 写尝试触发 illegal-instruction。具体字段的可写性、读回值和副作用规则仍适用。

容易混淆 / 常见误区

rd=x0 只抑制 CSR 读取和读副作用;不会把 CSRRW 变成不写 CSR 的指令。
rs1=x0 会向 CSR 写入零值;这不同于 CSRRS/CSRRC 的只读特例。
CSR 地址字段为 12 位;具体 CSR 的可写位、读回值和字段副作用由该 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 写入。