flycamelaaa 发表于 2023-11-9 09:52

RISC-V的基础指令模块


RISC-V有六种基本指令格式:
[*]R 类型指令,用于寄存器-寄存器操作
[*]I 型指令,用于短立即数和访存 load 操作
[*]S 型指令,用于访存 store 操作
[*]B 类型指令,用于条件跳转操作
[*]U 型指令,用于长立即数
[*]J 型指令,用于无条件跳转
以RV32为例
如下图所示:

R 类型指令
R类型指令将32位划分成6个区域:

opcode是操作码,占了7bit,在指令格式的0-6bit位上
rd (Destination Register)是目的寄存器,占了5bit,在指令格式的7-11bit位上
funct3+funct7是两个操作字段。funct3占了3bit,在指令格式的12-14bit位上;funct7占了7bit,在指令格式的25-31bit位上。
rs1 (Source Register #1)是第一个源操作数寄存器,占了5bit,在指令格式的15-19bit位上。
rs2 (Source Register #2)是第二个源操作数寄存器,占了5bit,在指令格式的25-31bit位上。


I类型指令
I类型指令将32位划分成5个区域:

opcode是操作码,占了7bit,在指令格式的0-6bit位上
rd (Destination Register)是目的寄存器,占了5bit,在指令格式的7-11bit位上
funct3是操作字段。funct3占了3bit,在指令格式的12-14bit位上。
rs1 (Source Register #1)是第一个源操作数寄存器,占了5bit,在指令格式的15-19bit位上。
存放12位的立即数——imm,在指令格式的20-31bit位上。
I类型指令可以用于:

寄存器-立即数的运算
加载指令
格式上只有一个字段不同于r格式,rs2和funct7替换为12位符号立即数(immediate字)imm。immediate字段为补码值,所以它可以表示从-2"到2"-1之间的整数。当I型格式用于加载指令时,immediate字段表示一个字节偏移量,所以加载双字指令可以取相对于基址寄存器rd中基地址偏移±(2"或2048)字节(±(2或256)个双字)的任何双字。

指令格式展示:
寄存器-立即数的运算

注:其中画圈表示位移方向0表示向左移,1表示向右移
[*]SLLI:是逻辑左移,低位补零
[*]SRLI:是逻辑右移, 高位补零
[*]SRAI:是算术右移,高位补原来高位。





flycamelaaa 发表于 2023-11-9 09:55

B类型指令
B类型指令将32位划分成6个区域:

opcode是操作码,占了7bit,在指令格式的0-6bit位上
imm+imm+imm+imm:立即数分成四个:
存放第11位的立即数——imm,在指令格式的第7bit位上;
存放第1位到第5位的立即数——imm,在指令格式的8-11bit位上;
存放后6位的立即数——imm,在指令格式的25-30bit位上;
存放第12位的立即数——imm,在指令格式的31bit位上。
注:imm被丢弃,因为它始终为零。
funct3是操作字段。funct3占了3bit,在指令格式的12-14bit位上。
rs1 (Source Register #1)是第一个源操作数寄存器,占了5bit,在指令格式的15-19bit位上。
rs2 (Source Register #2)是第二个源操作数寄存器,占了5bit,在指令格式的25-31bit位上。
B类型指令属于有条件的分支。RV32I 可以比较两个寄存器并根据比较结果上进行分支跳转。比较可以是:相等(beq),不相等 (bne),大于等于(bge),或小于(blt)。最后两种比较有符号比较,RV32I 也提供相应的无符号版本比较的:bgeu 和 bltu。剩下的两个比较关系(大于和小于等于)可以通过简单地交换两个操作数,即可完成比较。因为 x < y 表示 y > x 且 x ≥ y表示 y ≤ x。

RISC-V汇编语言包含两个决策类指令,类似于带go to的if语句。
[*]第一条指令是:

该指令表示如果寄存器rs1中的值等于寄存器rs2中的值,则转到标签为L1的语句执行。助记符beq代表相等则分支。
[*]第二条指令是:

该指令表示如果寄存器rs1中的值不等于寄存器rs2中的值,则转到标签为L1的语句执行。助记符bne代表不等则分支。这两条指令通常称作条件分支指令。注:PC 相对寻址在后续补充U类型指令U类型指令将32位划分成3个区域:
opcode是操作码,占了7bit,在指令格式的0-6bit位上rd (Destination Register)是目的寄存器,占了5bit,在指令格式的7-11bit位上imm:存放高20位的立即数——imm,在指令格式的12-31bit位上U类型指令包含两种指令
[*]LUI – 加载高位立即数
[*]AUIPC – 立即数地址添加到PC寄存器中

之前的类型指令中,已经有了12位的立即数作为表示常量。虽然常量通常很短并且适合12位,但有时它们也会更大。RISC-V指令系统包括指令 load upper immediate(取立即数高位,lui),用于将高20位常数加载到寄存器的第31位到第12位。将寄存器的低12位用0填充。该指令会与ADDI指令一起使用,目的是将低12位写入目标寄存器,以实现对32位的寄存器数值设置。
LUI x10 0x87654 # x10 = 0x87654000
ADDI x10,x10,0x321 # x10 = 0x87654321

注:由于ADDI的12位立即数最高位是符号位。例如:

如何利用LUI加载0xDEADBEEF



J类型指令
J类型指令将32位划分成3个区域:

opcode是操作码,占了7bit,在指令格式的0-6bit位上
rd (Destination Register)是目的寄存器,占了5bit,在指令格式的7-11bit位上
imm+imm+imm+imm:
存放第1位到第10位的立即数——imm,在指令格式的21-30bit位上;
存放11位的立即数——imm,在指令格式的20bit位上;
存放第12位到第19位的立即数——imm,在指令格式的12-19bit位上;
存放第20位的立即数——imm,在指令格式的31bit位上;


LOVEEVER 发表于 2023-11-29 19:55

楼主这个学习到了,确实很简单

duo点 发表于 2023-12-20 14:43

RISC-V的基础指令模块是RV32I,它是RISC-V指令集架构的核心部分,为编译器、汇编器和操作系统开发人员提供了稳定的研发目标。
页: [1]
查看完整版本: RISC-V的基础指令模块