Bootstrap

【RISCV 常见汇编指令学习 1.2 -- CSRW | CSRR | XORI | ANDI | DRET | J | JR】

Overview

在 RISCV 汇编中,不同类型的指令用于完成控制寄存器操作、内存存取、位操作、跳转以及返回等功能。下面将逐对详细介绍这些指令,并配合示例说明其用途和工作机制。
本文将 详细介绍 RISCV 中的汇编指令 CSRW 和 CSRR 及 SW 和 lw 及 XORI 和 ANDI 及 J 与 JR 及 ret 与 dret,每一对都举例介绍

1. CSRW 与 CSRR

功能说明

  • CSRW(CSR Write) :将通用寄存器中的值写入指定的控制和状态寄存器(CSR)。

  • CSRR(CSR Read) :从指定的 CSR 中读取值到通用寄存器中。
    这两条指令用于管理 CPU 的特殊寄存器,常见于调试或权限管理中。例如,通过 CSRW 指令可以将当前调试相关的状态存入 dscratch 寄存器,而 CSRR 可用于读取 mhartid(硬件线程编号)来确定当前执行的 hart。
    示例

	csrw dscratch0, s0      # 将寄存器 s0 的值写入调试专用寄存器 dscratch0
    csrr s1, mhartid        # 从 mhartid 寄存器读取当前 hart ID 到 s1

上述指令通常用于保存和获取调试状态以及硬件线程信息[2 ][1 ]。

2. SW 与 lw

功能说明

  • SW(Store Word) :将一个 32 位寄存器中的数据存入内存地址中。

  • LW(Load Word) :从指定内存地址加载一个 32 位数据到寄存器中。
    这两条指令实现内存与寄存器之间的数据传输,是程序数据存取的基本手段。
    示例

	sw s0, 396(zero)       # 将 s0 中的值存入地址 (zero + 396),396 十进制约等于 0x18c
    lw s1, 384(zero)       # 从地址 (zero + 384,即 0x180) 加载数据到 s1

这种数据传输操作常用于保存计算结果或传递数据,例如在函数调用时保存现场或交换数据[3 ]。

3. XORI 与 ANDI

功能说明

  • XORI(XOR Immediate) :对寄存器中的数据与一个立即数进行按位异或操作,并将结果存回目标寄存器。

  • ANDI(AND Immediate) :对寄存器中的数据与一个立即数进行按位与操作,将结果存回目标寄存器。
    这两条指令用于进行位级运算,常用来修改、清零或提取数据的特定位。
    示例

	xori s1, s1, 1024      # 将 s1 与立即数 1024 (0x400) 异或,用于切换特定位
    andi s0, s0, 0         # 将 s0 与 0 做按位与运算,结果 s0 被清零

这种操作在条件判断、位掩码操作及状态标志修改中十分常见[2 ][1 ]。

4. J 与 JR

功能说明

  • J(Jump) :无条件跳转到一个指定的立即地址。RISCV 中 J 通常为伪指令,其本质为 jal x0, offset,即跳转而不保存返回地址。

  • JR(Jump Register) :跳转到一个由寄存器指定的地址。它通常用来实现函数调用的返回或间接跳转。
    示例

	j 0x184                # 无条件跳转到当前 PC 加偏移 0x184 的地址
    jr ra, 0               # 使用寄存器 ra 的内容进行跳转(通常 ret 的实现方式)

这里,J 指令常用于静态的代码跳转,而 JR 则可实现动态跳转,如函数调用返回(利用 jalr x0, ra, 0 实现 ret)。[4 ][5 ]。

5. ret 与 dret

功能说明

  • ret :传统意义的返回指令,通常是 jalr x0, ra, 0,用于从函数返回,跳转到存放在 ra 寄存器中的返回地址。

  • dret :调试返回指令,用于从调试异常或调试模式中返回到正常执行状态。dret 指令会恢复调试之前的状态,使程序继续运行。
    示例

	ret                    # 从函数中返回,等价于 jalr x0, ra, 0
	dret                   # 从调试模式中退出,恢复正常程序执行

在调试过程中,dret 用于退出 ebreak 断点调试状态,而 ret 则用于正常的函数调用返回。两者的主要区别在于应用场景和上下文恢复机制[6 ][7 ]。


6. 总结

本文详细介绍了 RISCV 汇编中几组常用指令对及其使用场景:

  • CSRW/CSRR :用于写入和读取控制与状态寄存器,支持调试和状态管理。

  • SW/lw :实现内存与寄存器间数据传输,是数据存取的基础。

  • XORI/ANDI :进行位运算操作,常用于状态标志和掩码处理。

  • J/JR :实现无条件和寄存器间接跳转,支持静态与动态跳转。

  • ret/dret :分别用于函数返回与调试模式退出,帮助程序在不同执行环境中正确恢复状态。

这些指令构成了 RISCV 汇编编程的基础,理解它们的功能和使用场景对于开发高效、正确的底层软件至关重要。通过具体的示例代码,我们可以看到每条指令在实际代码中的应用,以及它们如何协同完成程序流程控制和状态管理[1 ][2 ][3 ][4 ][5 ][6 ][7 ][8 ].

🌐 Sources

  1. blog.csdn.net - RISC-V基础指令之lw和sw(包含使用说明及实例) 原创

  2. blog.csdn.net - RISCV - 2 “Zicsr“, CSR Instructions 原创

  3. ithelp.ithome.com.tw - DAY4: RISC-V: CSR指令用法 - iT 邦幫忙

  4. www.cnblogs.com - 一起学RISC-V汇编第4讲之指令格式

  5. stackoverflow.com - Using GCC to produce readable assembly?

  6. five-embeddev.com - RISC-V “V” Vector Extension / Privileged ISA - CSR Instructions

  7. www.sunnychen.top - RISC-V基本指令集概述 - SunnyChen的小窝

;