risc-V学习日记(5):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. 高位立即数与地址构造

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

LUI 代码演示

	.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. 控制转移指令

无条件跳转

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

JALR代码演示

	.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

在这里插入图片描述

条件分支

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

BNE代码演示

	.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. 内存访问指令

加载指令

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

存储指令

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

4. 整数运算指令

立即数运算

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

ADDI代码演示

	.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

在这里插入图片描述

移位运算

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

SLLI代码演示

	.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

在这里插入图片描述

寄存器-寄存器运算

指令格式功能描述示例
ADDadd rd, rs1, rs2rs1 + rs2,结果写入 rd。add x5, x6, x7
SUBsub rd, rs1, rs2rs1 - rs2。sub x5, x6, x7
SLLsll rd, rs1, rs2逻辑左移 rs1,移位数为 rs2 的低 5 位。sll x5, x6, x7
SLTslt rd, rs1, rs2若 rs1 < rs2(有符号比较),则 rd=1,否则 rd=0。
SLTUsltu rd, rs1, rs2无符号比较 rs1 < rs2,结果写入 rd。sltu x5, x6, x7
XORxor rd, rs1, rs2按位异或。xor x5, x6, x7 → x5 = x6 ^ x7
SRLsrl rd, rs1, rs2逻辑右移(高位补 0)。srl x5, x6, x7
SRAsra rd, rs1, rs2算术右移(高位补符号位)。sra x5, x6, x7
ORor rd, rs1, rs2按位或。or x5, x6, x7 → x5 = x6
ANDand rd, rs1, rs2按位与。and x5, x6, x7 → x5 = x6 & x7

ADD代码演示

	.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. 系统与同步指令

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

结语

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

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

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

下期见咯~

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值