网站Logo 网友马大帅的博客

什么是RISC-V?

ughostx
41
2025-12-18

基础介绍

  • RISC:精简指令集

  • V:第五代,也有变化的含义

RISC-V 是一套开放许可证书、免费的、由基金维护的、一个整数运算指令集外加多个扩展指令集的CPU 结构规范(ISA)。

整数运算指令集 + 扩展指令集

指令集名称:以RV为前缀,加处理器位宽,加指令集合

RV【###】【IAC....】

eg: RV64IMAC,表示64 位 RISC-V, 支持整型指令(I)、乘除法指令(M)、原子指令(A)和压缩指令(C)。

  • 基础的整型指令必须要支持,其它的可选扩展支持

寄存器

rsic-v的标准架构寄存器有32个通用寄存器加一个pc寄存器,不同的cpu位宽只有寄存器的位宽不一样,数量是一样的。其中x0为固定0值寄存器,读取为0值,写入会被忽略。如果要实现F/D扩展指令的cpu,则需要额外支持32个浮点寄存器。如果实现只支持RV32E指令集的嵌入式CPU,则可以将32个通用寄存器缩减为16个通用寄存器。

寄存器

ABI 名称

说明

x0

zero

0值寄存器,硬编码为0,写入数据忽略,读取数据为0

x1

ra

用于返回地址(return address)

x2

sp

用于栈指针(stack pointer)

x3

gp

用于通用指针 (global pointer)

x4

tp

用于线程指针 (thread pointer)

x5

t0

用于存放临时数据或者备用链接寄存器

x6~x7

t1~t2

用于存放临时数据寄存器

x8

s0/fp

需要保存的寄存器或者帧指针寄存器

x9

s1

需要保存的寄存器

x10~x11

a0~a1

函数传递参数寄存器或者函数返回值寄存器

x12~x17

a2~a7

函数传递参数寄存器

x18~x27

s2-s11

需要保存的寄存器

x28~x31

t3~t6

用于存放临时数据寄存器

ABI: 应用程序二进制接口,可以理解为寄存器别名,高级语言在生成汇编会用到。

特权级别

跟arm类似,rsic-v也有不同的特权级别,不同的特权级别下能访问的系统资源不同。

RISC-V 的规范文档定义了四个特权级别(privilege level),如下表所示。(类似于arm的EL0~EL3)

名称

级别

缩写

编码

用户,应用程序特权级

0

U

00

管理员特权级

1

S

01

虚拟机监视特权级

2

H

10

机器特权级

3

M

11

一个RISC-V 硬件线程(hart),相当于一个CPU 内独立的可执行核心,在任意时刻,只能运行在某一个特权级上,这个特权级由CSR(控制和状态寄存器)指定配置。

  • 机器特权级(M):RISC-V 中 hart 可以执行的最高权限模式。在M 模式下运行的 hart,对内存、I/O 和一些必要的底层功能(启动和系统配置)有着完全的控制权。它是唯一一个所有标准RISC-V CPU 都必须实现的权限级。

  • 虚拟机监视特权级(H):为了支持虚拟机监视器而定义的特权级。

  • 管理员特权级(S):主要用于支持现代操作系统,如Linux、FreeBSD和 windows 等

  • 用户应用特权级(U):用于运行应用程序,同样也适用于嵌入式系统。

指令介绍

RV32I

整数计算

算术指令:add(加),sub(减)

ADD rd, rs1, rs2

用于对两个寄存器中的值进行加法操作。结果存储在目标寄存器中。

  • rd:目标寄存器,存储结果。

  • rs1:源寄存器 1。

  • rs2:源寄存器 2。

SUB rd, rs1, rs2

用于对两个寄存器中的值进行减法操作。结果存储在目标寄存器中。

  • rd:目标寄存器,存储结果。

  • rs1:源寄存器 1。

  • rs2:源寄存器 2。

逻辑指令:and(按位与), or按位或, xor(按位异或)

AND rd, rs1, rs2

用于对两个寄存器中的值进行按位与操作。结果存储在目标寄存器中

  • rd:目标寄存器,存储结果。

  • rs1:源寄存器 1。

  • rs2:源寄存器 2。

OR rd, rs1, rs2

用于对两个寄存器中的值进行按位或操作。结果存储在目标寄存器中。

  • rd:目标寄存器,存储结果。

  • rs1:源寄存器 1。

  • rs2:源寄存器 2。

XOR rd, rs1, rs2

用于对两个寄存器中的值进行按位异或操作。结果存储在目标寄存器中。

  • rd:目标寄存器,存储结果。

  • rs1:源寄存器 1。

  • rs2:源寄存器 2。

加载和存储

常见的有32位读取和加载指令lw和sw。

LW rd, offset(rs1)
LW x5, 0(x1)  ; 从内存地址 x1 加上偏移量 0 处加载一个字到 x5
SW rs2, offset(rs1)
SW x5, 0(x1)  ; 将 x5 中的数据存储到内存地址 x1 加上偏移量 0 处

rsic-v 不支持延迟加载。

rsic-v 是小端字节序。

条件分支

常见的有相等(beq),不相等 (bne),大于等于(bge),或小于(blt)。

BEQ rs1, rs2, offset
BEQ x1, x2, label  ; 如果 x1 和 x2 相等,则跳转到 label

rsic-v 不支持延迟跳转。

获取PC的方法:当前的 PC 可以通过将 auipc 的 U 立即数字段设置为 0 来获得。

检查溢出:rsic-v 依赖软件检查溢出。

无条件跳转

常见的无条件跳转指令:jal,用于无条件跳转到指定的标签,并且在跳转之前将返回地址(即跳转指令的下一条指令的地址)保存到一个寄存器中

JAL rd, offset
JAL x1, label  ; 跳转到 label,并将下一条指令的地址存储到 x1 中

动物装饰