RISC-V指令详解-计组

常见指令类型

R型指令

一、指令格式

funct7(7 bit) rs2(5 bit) rs1(5 bit) funct3(3 bit) rd(5 bit) opcode(7 bit)

其中:

  • rs1(5 bit):存储第一个操作数所在的寄存器号
  • rs2(5 bit):存储第二个操作数所在的寄存器号
  • rd(5 bit): 存储结果数所在的寄存器号

二、示例

Example One:
add x7, x8, x9

funct7(7 bit) rs2(5 bit) rs1(5 bit) funct3(3 bit) rd(5 bit) opcode(7 bit)
******* 01001(9) 01000(8) *** 00111(7) *******

I型指令

一、指令格式

imm(12 bit) rs1(5 bit) funct3(3 bit) rd(5 bit) opcode(7 bit)

其中:

  • rs1(5 bit):存储第一个操作数所在的寄存器号
  • imm(12 bit):是一个12位的立即数字段,用于提供操作数的立即数值。这个立即数可以被有符号扩展到32位,并与寄存器rs1的内容进行运算。
  • rd(5 bit): 存储结果数所在的寄存器号

注意:由于I型指令中仅有rs1,没有rs2,所以该类型指令的第二个操作数一定是立即数,第一个操作数一定是用寄存器地址表示

二、示例

Example One:
addi x7, x8, 20

imm(12 bit) rs1(5 bit) funct3(3 bit) rd(5 bit) opcode(7 bit)
10100(20) 01000(8) *** 00111(7) *******

Example Two:
ld x7, 30(x8)

imm(12 bit) rs1(5 bit) funct3(3 bit) rd(5 bit) opcode(7 bit)
0000 0001 1110(30) 01000(8) *** 00111(7) *******

S型指令

一、指令格式

imm[11:5](7 bit) rs2(5 bit) rs1(5 bit) funct3(3 bit) imm[4:0](5 bit) opcode(7 bit)

其中:

  • rs1(5 bit):存储基址寄存器号
  • rs2(5 bit):存储将要被保存在内存中的数据的寄存器号
  • imm(12 bit):存储偏移量

二、示例

Example One:
sd x10, 16(x5)

imm[11:5](7 bit) rs2(5 bit) rs1(5 bit) funct3(3 bit) imm[4:0](5 bit) opcode(7 bit)
0000 000 01010(10) 00101(5) *** 1 0000 *******

SB型指令

一、指令格式

imm[12] imm[10:5] rs2 rs1 funct3 imm[4:1] imm[11] opcode

其中:

  • immediate(12 bit):表示分支目标相对于当前指令地址的偏移量。
  • rs1(5 bit):存储用于比较的数值的寄存器号
  • rs2(5 bit):存储用于比较的数值的寄存器号

二、示例

Example One:
bne x9, x10, 100

imm[12] imm[10:5] rs2 rs1 funct3 imm[4:1] imm[11] opcode
0 001 100 01010(10) 01001(9) *** 0 010 0 *******

U型指令

一、指令格式

imm[31:12] rd(5 bit) opcode(7 bit)

其中:

  • imm[31:12]:20 位的立即数字段,表示要加载到目标寄存器的高位立即数。
  • rd:目标寄存器,用于存储加载的立即数。
  • U型指令中常见的仅有lui指令和auipc指令

二、示例

lui x1, 0x00001

imm[31:12] rd(5 bit) opcode(7 bit)
0000 0000 0000 0000 0001 00001 *******

UJ型指令

一、指令格式

offset(20 bit) rd opcode
offset[20] offset[10:1] offset[11] offset[19:12] rd 110111

注意仅有jal指令属于UJ型指令,且UJ型跳转指令的立即数同样需要进行一位移位操作,以半字为单位进行指令寻址

二、示例

Example One:
jal x1, 20

opcode rd offset(20 bit)
110111 0 0001 0000 0000 0000 0001 0100(20)

常见指令释义

  1. add(R-type)

add rd, rs1, rs2

reg[rd] = reg[rs1] + reg[rs2]
2. ld(I-type)

ld rd, offset(rs1)

reg[rd] = mem[reg[rs1] + offset]
从地址为寄存器rs1的值加offset的主存中读一个双字,注意算式 (rs1+offset) 的寻址单位是字节。其中offset = imm,imm是12位补码。
3. sd(S-type)

sd rs1, offset(rs2)

mem[reg[rs2] + offset] = reg[rs1]
把寄存器rs1的值存入地址为寄存器rs2的值加offset的主存中,其中offset = imm,imm是12位补码。
4. beq(SB-type)

beq rs1, rs2, offset

if (reg[rs1] == reg[rs2])
    PC = PC + offset*2;
else 
    PC = PC + 4;

注意offset是13位有符号数,用补码形式存储
5. jal(J-type)

jal rd offset

reg[rd] = PC + 4;
PC = PC + offset*2;

注意offset是20位有符号数,用补码形式存储
6. jalr(J-type)

jalr rd, rs1, offset


int temp = (reg[rs1] + offset) & ~1;
reg[rd] = PC + 4;
PC = temp;

寄存器 rs1 和符号扩展的立即偏移量之和将作为跳转指令的地址
而寄存器rd中将会保存当前PC地址加4(当前指令的下一条指令的地址)
其中offset是12位有符号数

你可能感兴趣的:(risc-v,笔记)