RISC-V指令简介

RISC-V指令简介

RISC-V指令的长度是固定的,由处理器的位数决定。

R型指令

RISC-V中的R型指令是用于寄存器-寄存器操作的基本指令格式,主要用于执行算术运算、逻辑运算和移位操作等计算密集型任务。

R型指令采用固定的32位编码格式,具体字段分布如下:

字段位置 31-25 24-20 19-15 14-12 11-7 6-0
字段名称 funct7 rs2 rs1 funct3 rd opcode
位宽 7位 5位 5位 3位 5位 7位

各字段功能说明:

  • opcode :7位操作码,固定为0110011,标识该指令为R型指令
  • rd:5位目的寄存器编号,用于存放运算结果
  • funct3:3位功能码,进一步区分不同类型的R型指令
  • rs1:5位第一个源操作数寄存器编号
  • rs2:5位第二个源操作数寄存器编号
  • funct7:7位扩展功能码,与funct3配合使用,更精确地定义操作类型

算术运算指令

  • ADD rd, rs1, rs2 :寄存器加法,rd = rs1 + rs2
  • SUB rd, rs1, rs2 :寄存器减法,rd = rs1 - rs2

逻辑运算指令

  • AND rd, rs1, rs2 :按位与操作,rd = rs1 & rs2
  • OR rd, rs1, rs2 :按位或操作,rd = rs1 | rs2
  • XOR rd, rs1, rs2 :按位异或操作,rd = rs1 ^ rs2

移位操作指令

  • SLL rd, rs1, rs2 :逻辑左移,rd = rs1 << rs2
  • SRL rd, rs1, rs2 :逻辑右移,rd = rs1 >> rs2(高位补0)
  • SRA rd, rs1, rs2 :算术右移,rd = rs1 >> rs2(高位补符号位)

比较指令

  • SLT rd, rs1, rs2 :有符号比较,如果rs1 < rs2rd = 1,否则rd = 0
  • SLTU rd, rs1, rs2 :无符号比较,如果rs1 < rs2rd = 1,否则rd = 0

编码示例

add x5, x6, x7指令为例:

  • 二进制编码:0000000 | 00111 | 00110 | 000 | 00101 | 0110011
  • 功能:将x6和x7寄存器中的值相加,结果存入x5寄存器

I型指令

I型指令是RISC-V指令集中非常重要的一类,主要用于立即数操作数据加载无条件跳转等功能。

字段位置(高位到低位) 字段名称 位宽 功能描述
31-20 imm[11:0] 12位 12位立即数,在使用时会进行符号扩展至32位
19-15 rs1 5位 第一个源操作数寄存器地址
14-12 funct3 3位 功能码,与opcode配合指定具体操作(如ADD、LOAD等)
11-7 rd 5位 目的寄存器地址,用于存放操作结果
6-0 opcode 7位 操作码,标识指令类型(如I型指令的操作码为0010011或0000011等)

主要类型与功能

I型指令根据其具体功能,主要可以分为以下三类:

  • 寄存器-立即数运算指令

    这是最基础的I型指令,其基本操作为:Reg[rd] = Reg[rs1] op Imm。最常见的例子是 ADDI (立即数加法)指令,例如 ADDI x5, x6, 10 表示将寄存器x6的值加上10,结果存入寄存器x5。除了加法,这类指令还包括按位逻辑操作(如 ANDI, ORI, XORI)、移位操作(如 SLLI, SRLI, SRAI)和比较操作(如 SLTI, SLTIU)等。

  • 加载指令

    加载指令用于从内存中读取数据到寄存器,属于I型指令。其地址由寄存器rs1的值加上12位的符号扩展偏移量(offset)形成。例如 LW (加载字)指令 LW x10, 0(x1),表示从以寄存器x1的值为基地址、偏移量为0的内存位置读取一个32位的字,然后存入寄存器x10。类似的指令还有加载字节(LB/LBU)和加载半字(LH/LHU)等。

  • 跳转链接寄存器指令
    JALR (跳转并链接寄存器)指令也采用I型格式。它用于子程序调用或跳转到由寄存器指定的地址,其操作通常为 x[rd] = PC + 4; PC = x[rs1] + imm。例如 JALR ra, 40(x10) 会跳转到地址为 x10 + 40 的地方执行,同时将返回地址(下一条指令的地址PC+4)存入ra寄存器。

S型指令

S型指令是RISC-V指令集中专门用于写存储器(Store)操作的一类指令,其核心功能是将寄存器中的数据存储到内存中。

核心特征 S型指令的对应设计
主要功能 将寄存器的值写入内存(Store操作)
操作码 (opcode) 0100011
指令格式字段 (从高位到低位) imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode
操作的寄存器 两个源寄存器:rs1(基地址寄存器)、rs2(要存储的数据来源寄存器)
立即数特点 12位立即数(作为地址偏移量),但被拆分编码在指令的不同位置
常见指令示例 sb (存储字节), sh (存储半字), sw (存储字)

指令格式详解

S型指令的32位编码格式颇具巧思,其设计旨在与其他指令格式保持规整性同时,优化指令解码。它的12位立即数(imm)被分为两部分,分散在指令中:

  • imm[11:5]:位于指令的31-25位。
  • imm[4:0]:位于指令的11-7位。

当CPU执行S型指令时,需要先将这两个部分组合起来,并进行符号扩展 ,生成一个32位的有效地址偏移量。存储操作的内存地址由公式 内存地址 = Reg[rs1] + 符号扩展后的立即数 计算得出。

常见指令与操作过程

常见的S型指令通过funct3字段区分具体操作类型,例如:

  • sw rs2, offset(rs1) :存储字(32位)。将寄存器rs2中的32位数据写入内存。
  • sh rs2, offset(rs1) :存储半字(16位)。仅将寄存器rs2的低16位数据写入内存。
  • sb rs2, offset(rs1) :存储字节(8位)。仅将寄存器rs2的低8位数据写入内存。

其数据通路的关键操作可概括为:计算有效地址,然后根据funct3指示的数据宽度,将rs2寄存器中的相应数据写入该内存地址。

SB型指令

SB型指令是RISC-V指令集中用于条件分支跳转的一类重要指令,它根据两个寄存器的值比较结果来决定程序的执行流程。

核心特征 SB型指令的对应设计
主要功能 条件分支跳转(Conditional Branch)
操作码 (opcode) 1100011
指令格式字段 (从高位到低位) imm[12,10:5] | rs2 | rs1 | funct3 | imm[4:1,11] | opcode
操作的寄存器 两个源寄存器:rs1rs2(用于比较)
立即数特点 12位立即数(作为偏移量),但被拆分并旋转编码在指令中
跳转地址计算 目标地址 = 当前指令地址 + 符号扩展后的立即数左移1位后的值

常见指令与功能

SB型指令通过funct3字段来区分不同的比较条件。以下是RV32I基础指令集中的所有SB型指令:

指令 语法 功能描述(伪代码) 比较类型
BEQ beq rs1, rs2, imm rs1 == rs2,则 PC += imm << 1 相等
BNE bne rs1, rs2, imm rs1 != rs2,则 PC += imm << 1 不相等
BLT blt rs1, rs2, imm rs1 < rs2,则 PC += imm << 1 有符号数小于
BGE bge rs1, rs2, imm rs1 >= rs2,则 PC += imm << 1 有符号数大于等于
BLTU bltu rs1, rs2, imm rs1 < rs2,则 PC += imm << 1 无符号数小于
BGEU bgeu rs1, rs2, imm rs1 >= rs2,则 PC += imm << 1 无符号数大于等于

关键点说明

  • 跳转范围 :由于12位立即数经过符号扩展后左移1位,SB型指令的跳转范围是相对于当前指令的 ±4KB 地址空间。
  • 有符号与无符号BLT/BGE 将寄存器值当作有符号整数 进行比较,而 BLTU/BGEU 则当作无符号整数进行比较。这在处理如地址或特定编码的数值时至关重要。

U型指令

RISC-V指令集中的U型指令(Upper Immediate Instructions)主要用于处理20位的大立即数,这些指令的特点是将立即数放置在寄存器的高位,低位则进行补零或与其他地址组合。

| 核心特征 | U型指令的对应设计 |

| :--- | :--- | :--- |

| 主要功能 | 处理20位大立即数,用于构建32位常数或绝对地址 |

| 操作码 (opcode) | 0110111 (LUI) 或 0010111 (AUIPC) |

| 指令格式字段 (从高位到低位) | imm[31:12] | rd | opcode |

| 操作的寄存器 | 一个目的寄存器:rd(用于存放结果) |

| 立即数特点 | 20位立即数(位于指令的31-12位),加载到寄存器的高20位 |

U型指令的编码格式非常规整,仅包含三个部分:

  • imm[31:12]:20位的立即数,占据指令的最高20位(31-12位)。
  • rd:5位的目的寄存器编号,用于存放操作结果。
  • opcode:7位的操作码,标识指令的具体类型。

常见的U型指令主要有两条:

  1. LUI(Load Upper Immediate)

    • 操作 :将20位的立即数左移12位(即填充低12位为0),然后符号扩展至32位,结果写入目的寄存器 rd
    • 语法lui rd, imm20
    • 示例lui x10, 0x12345 执行后,寄存器x10中的值为 0x12345000。这条指令常用于构建大的常数或绝对地址的高位部分。
  2. AUIPC(Add Upper Immediate to PC)

    • 操作 :将20位的立即数左移12位并进行符号扩展,然后与当前程序计数器(PC)的值相加 ,结果写入目的寄存器 rd
    • 语法auipc rd, imm20
    • 示例auipc x10, 0 可以用于获取当前PC的值(因为立即数为0,结果就是PC的值)。这条指令在与I型指令(如addi)或J型指令(如jalr)结合使用时,可以实现相对于PC的远距离跳转或构建位置无关代码的地址。

UJ型指令

UJ型指令是RISC-V指令集中用于实现长距离无条件跳转 的关键指令格式,最主要的就是JAL(Jump and Link)指令。

核心特征 UJ型指令的对应设计
主要功能 长距离无条件跳转(Jump),主要用于函数调用和远距离跳转
操作码 (opcode) 1101111
指令格式字段 (从高位到低位) imm[20,10:1,11,19:12] | rd | opcode
操作的寄存器 一个目的寄存器:rd(用于保存返回地址)
立即数特点 20位立即数(作为偏移量),但被拆分并旋转编码在指令中
跳转地址计算 目标地址 = 当前指令地址 + 符号扩展后的立即数左移1位后的值

当CPU执行UJ型指令时,硬件会按照 imm[20] | imm[10:1] | imm[11] | imm[19:12] 的顺序取出这些比特位,然后进行符号扩展 生成一个21位的有符号立即数。这个立即数会左移1位 (即乘以2),因为RISC-V的所有指令地址都必须是2字节对齐的,这样能保证目标地址的有效性。最终,跳转目标地址由公式 目标地址 = PC + 偏移量 计算得出。

JAL

UJ型指令中最核心的就是JAL(Jump and Link)指令,它的操作可以概括为以下两步:

  1. 保存返回地址 :将下一条指令的地址(即PC + 4)写入目的寄存器rd中。
  2. 跳转:将程序计数器(PC)设置为计算出的目标地址。

JAL指令的语法是:jal rd, offset

  • 一个常见的用法是jal ra, target,其中ra(即x1寄存器)通常用作链接寄存器,专门用于存放函数调用后的返回地址。
  • 如果跳转后不需要返回(比如单纯的跳转),可以将rd设置为x0(零寄存器),因为写入x0的值会被丢弃,例如jal x0, target

寻址方式

  • 立即数寻址
  • 寄存器寻址
  • PC相对寻址
  • 基址寻址
相关推荐
cooldream20092 天前
基于 RISC-V VisionFive 的桌面数字时钟项目实战
嵌入式硬件·risc-v·嵌入式开发
MounRiver_Studio2 天前
RISC-V IDE MRS2使用笔记(三):编译后函数调用分析
ide·笔记·risc-v
MounRiver_Studio2 天前
RISC-V IDE MRS2使用笔记(二): 编译后Memory分析
ide·笔记·单片机·嵌入式·risc-v
国科安芯3 天前
AS32系列MCU芯片TIM模块的捕获和比较
单片机·嵌入式硬件·fpga开发·架构·risc-v
Liangwei Lin9 天前
计算机组成原理
计算机组成原理
云雾J视界9 天前
FPGA+RISC-V架构解析:构建高效传感器数据采集系统
fpga开发·架构·uart·risc-v·i2c·adxl345
电子科技圈12 天前
IAR与Quintauris携手推进RISC-V汽车实时应用的功能安全软件开发
嵌入式硬件·安全·设计模式·编辑器·汽车·risc-v
Joey_Chen12 天前
补码是什么?为什么byte的范围是-128~127,负数要比整数多1个?
计算机组成原理
CinzWS13 天前
RISC-V RV32MCU 架构、启动与运行机制深度剖析
risc-v·exception