risc-V学习日记(4):RV32I指令集

这一期我们重新回到RISC-V的内容说明。

文章目录

基本指令集

指令格式

在基本ISA中,有四种核心指令格式(R/I/S/U),如图 2.2所示。所有的指令都是固定32位长度的,并且在存储器中必须在4字节边界对齐。当发生一个条件分支或者无条件转移而且目标地址不是对齐到4字节时, 将会产生一个指令地址不对齐的异常。 如果条件分支没有发生(not taken),那么将不会产生一个取指不对齐异常。

基于立即数处理,还有额外两种指令格式变种(SB/UJ)

指令集功能分类

RV32I指令集按照指令功能可以分为5类。

  1. Integer Computational Instructions【整数计算指令,下称使用中文】
  2. Loads and Store Instructions【访存指令】
  3. Control Transfer Instructions【控制转移指令】
  4. Memory Ordering Instructions【内存顺序指令】
  5. Environment Call and Breakpoints【环境调用和断点】

这5类指令包括了一种或多种指令格式,下面分类给出各部分指令的简要功能介绍。

指令集总览

RV32I 基本指令集有47条指令,如下图:

是不是很多,这里给大伙提供一个网站,可以在线直接查看 Risc-V的指令功能 ------ 跳转链接

指令详细说明

1. 高位立即数与地址构造

指令 格式 功能描述 示例
LUI lui rd, imm 将 20 位立即数 imm 左移 12 位,写入 rd 的高位,低位补 0。 lui x5, 0x12345 → x5 = 0x12345000
AUIPC auipc rd, imm 将 PC 当前值 + (imm << 12),结果写入 rd,用于构造全局地址或远跳转。 auipc x6

LUI 代码演示

bash 复制代码
	.text			# Define beginning of text section
	.global	_start		# Define entry _start

_start:
	lui x5, 0x12345		# int x5 = 0x12345 << 12
	addi x5, x5, 0x678	# x5 = x5 + 0x678
stop:
	j stop			# Infinite loop to stop execution

	.end			# End of file

2. 控制转移指令

无条件跳转

指令 格式 功能描述 示例
JAL jal rd, offset 跳转到 PC + offset,并将返回地址 PC+4 存入 rd(通常 rd=x1)。 jal x1, func → 调用函数 func
JALR jalr rd, rs1, imm 跳转到 rs1 + imm(地址最低位强制为 0),返回地址 PC+4 存入 rd。 jalr x0, x1, 0 → 跳转到 x1 并返回

JALR代码演示

bash 复制代码
	.text			# Define beginning of text section
	.global	_start		# Define entry _start

_start:
	li x6, 1
	li x7, 2
	jal x5, sum		# call sum, return address is saved in x5

stop:
	j stop			# Infinite loop to stop execution

sum:
	add x6, x6, x7		# x6 = x6 + x7
	jalr x0, 0(x5)		# return

	.end			# End of file

条件分支

指令 格式 功能描述 示例
BEQ beq rs1, rs2, offset 若 rs1 == rs2,跳转到 PC + offset。 beq x5, x6, loop → 相等则循环
BNE bne rs1, rs2, offset 若 rs1 != rs2,跳转。 bne x5, x0, exit → 非零则退出
BLT blt rs1, rs2, offset 若 rs1 < rs2(有符号比较),跳转。 blt x5, x6, less
BGE bge rs1, rs2, offset 若 rs1 >= rs2(有符号比较),跳转。 bge x5, x6, greater_eq
BLTU bltu rs1, rs2, offset 若 rs1 < rs2(无符号比较),跳转。 bltu x5, x6, uless
BGEU bgeu rs1, rs2, offset 若 rs1 >= rs2(无符号比较),跳转。 bgeu x5, x6, ugreater_eq

BNE代码演示

bash 复制代码
	.text			# Define beginning of text section
	.global	_start		# Define entry _start

_start:
	# i = 0
	# while (i < 5) i++;

	li x5, 0
	li x6, 5
loop:
	addi x5, x5, 1
	bne x5, x6, loop

stop:
	j stop			# Infinite loop to stop execution

	.end			# End of file

在这里插入图片描述

3. 内存访问指令

加载指令

指令 格式 功能描述 示例
LB lb rd, offset(rs1) 从 rs1 + offset 加载字节(符号扩展后写入 rd)。 lb x5, 4(x6) → 加载字节到 x5
LH lh rd, offset(rs1) 加载半字(符号扩展)。 lh x5, -8(x6)
LW lw rd, offset(rs1) 加载字(32 位数据)。 lw x5, 0(x6)
LBU lbu rd, offset(rs1) 加载无符号字节(高位补 0)。 lbu x5, 3(x6)
LHU lhu rd, offset(rs1) 加载无符号半字(高位补 0)。 lhu x5, 2(x6)

存储指令

指令 格式 功能描述 示例
SB sb rs2, offset(rs1) 将 rs2 的低 8 位存储到 rs1 + offset。 sb x5, 10(x6) → 存储字节
SH sh rs2, offset(rs1) 存储低 16 位。 sh x5, -4(x6)
SW sw rs2, offset(rs1) 存储 32 位。 sw x5, 0(x6)

4. 整数运算指令

立即数运算

指令 格式 功能描述 示例
ADDI addi rd, rs1, imm rs1 + 符号扩展的12位立即数,结果写入 rd。 addi x5, x6, -5 → x5 = x6 -5
SLTI slti rd, rs1, imm 若 rs1 < imm(有符号比较),则 rd=1,否则 rd=0。 slti x5, x6, 10 → 检查是否小于 10
SLTIU sltiu rd, rs1, imm 无符号比较 rs1 < imm,结果写入 rd。 sltiu x5, x6, 0xFFF
XORI xori rd, rs1, imm rs1 ^ 符号扩展的立即数。 xori x5, x6, 0xFFFF → 按位取反
ORI ori rd, rs1, imm rs1 符号扩展的立即数。
ANDI andi rd, rs1, imm rs1 & 符号扩展的立即数。 andi x5, x6, 0xFF → 取低8位

ADDI代码演示

bash 复制代码
	.text			# Define beginning of text section
	.global	_start		# Define entry _start

_start:
	li x6, 2		# x6 = 2
	addi x5, x6, 1		# x5 = x6 + 1

stop:
	j stop			# Infinite loop to stop execution

	.end			# End of file

移位运算

指令 格式 功能描述 示例
SLLI slli rd, rs1, shamt 逻辑左移 rs1,移位数为 shamt(0-31),结果写入 rd。 slli x5, x6, 2 → x5 = x6 << 2
SRLI srli rd, rs1, shamt 逻辑右移(高位补 0)。 srli x5, x6, 3
SRAI srai rd, rs1, shamt 算术右移(高位补符号位)。 srai x5, x6, 4

SLLI代码演示

bash 复制代码
	.text			# Define beginning of text section
	.global	_start		# Define entry _start

_start:
	li x6, 1		# x6 = 1
	slli x5, x6, 3		# x5 = x6 << 3

stop:
	j stop			# Infinite loop to stop execution

	.end			# End of file

寄存器-寄存器运算

指令 格式 功能描述 示例
ADD add rd, rs1, rs2 rs1 + rs2,结果写入 rd。 add x5, x6, x7
SUB sub rd, rs1, rs2 rs1 - rs2。 sub x5, x6, x7
SLL sll rd, rs1, rs2 逻辑左移 rs1,移位数为 rs2 的低 5 位。 sll x5, x6, x7
SLT slt rd, rs1, rs2 若 rs1 < rs2 (有符号比较),则 rd=1,否则 rd=0。
SLTU sltu rd, rs1, rs2 无符号比较 rs1 < rs2,结果写入 rd。 sltu x5, x6, x7
XOR xor rd, rs1, rs2 按位异或。 xor x5, x6, x7 → x5 = x6 ^ x7
SRL srl rd, rs1, rs2 逻辑右移(高位补 0)。 srl x5, x6, x7
SRA sra rd, rs1, rs2 算术右移(高位补符号位)。 sra x5, x6, x7
OR or rd, rs1, rs2 按位或。 or x5, x6, x7 → x5 = x6
AND and rd, rs1, rs2 按位与。 and x5, x6, x7 → x5 = x6 & x7

ADD代码演示

bash 复制代码
	.text			# Define beginning of text section
	.global	_start		# Define entry _start

_start:
	li x6, 1		# x6 = 1
	li x7, 2		# x7 = 2
	add x5, x6, x7		# x5 = x6 + x7

stop:
	j stop			# Infinite loop to stop execution

	.end			# End of file

5. 系统与同步指令

指令 格式 功能描述 示例
FENCE fence 内存屏障,确保其前后的内存访问顺序。 fence → 保证访存顺序
ECALL ecall 触发环境调用(如系统调用或切换到更高权限模式)。 ecall → 执行系统调用
EBREAK ebreak 触发调试断点,通常用于调试器介入。 ebreak → 进入调试模式

结语

这一期讲了RV32I的所有指令集,下一期我们来看看指令在CPU中是经过了那些过程才最终实现出来的。

感谢大伙观看,别忘了三连支持一下

大家也可以关注一下我的其它专栏,同样精彩喔~

下期见咯~

相关推荐
DXM052118 分钟前
牟乃夏《ArcGIS Engine地理信息系统开发教程》学习笔记3-地图基本操作与实战案例
开发语言·笔记·学习·arcgis·c#·ae·arcgis engine
qsmyhsgcs1 小时前
Java程序员转人工智能入门学习路线图(2025版)
java·人工智能·学习·机器学习·算法工程师·人工智能入门·ai算法工程师
Humbunklung2 小时前
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类矩阵QRectF)
笔记·python·学习·pyqt
每次的天空3 小时前
Android学习总结之Java篇(一)
android·java·学习
春眠不觉晓♞4 小时前
使用多线程快速向Excel中快速插入一万条数据案例
java·学习·excel
Mabnus5 小时前
文献分享:一种四价双特异性抗体的功能性和IgG样稳定性、药理学和可开发特性研究
学习
岁月不能老5 小时前
Linux-Part8-考试(学习Linux第8天)
linux·运维·学习
peter67686 小时前
kvm学习小结
学习
zcyf08097 小时前
kafka理论学习汇总
java·分布式·学习·kafka