RISC-V基础指令集

本集训营用的最多的指令集是RV64I基础,它包含了处理器指令集最核心的部分:整数计算、控制流和内存访问指令,指令简单明了,适合快速掌握。

下面是对 RV64I 基础指令集的详细介绍。

寄存器

  • x0-x31:32个整数寄存器。
  • f0-f31:32个浮点寄存器。
  • pc:程序计数器。
  • sp:堆栈指针。
  • ra:返回地址寄存器。

指令格式

指令格式如下:

opcode rd, rs1, rs2 [, imm]
  • opcode:指令的操作码。
  • rd:目标寄存器。
  • rs1:源寄存器1。
  • rs2:源寄存器2。
  • imm:立即数。

指令集

RV32I 基础指令集

RV32I 基础指令集包含了整数计算、控制流和内存访问指令。

  • 整数计算指令:ADD, SUB, ADDI, AND, OR, XOR, ANDI, SLL, SRL, SRA, SLT, SLTU, SLTI
  • 控制流指令:BEQ, BNE, BLT, BGE, JAL, JALR
  • 内存访问指令:LW, LH, LHU, LB, LBU, SW, SH, SB

整数计算指令

算术指令

  • ADD: 将两个寄存器的值相加,结果存储在目标寄存器中。
    ADD rd, rs1, rs2  # rd = rs1 + rs2
    
  • SUB: 将一个寄存器的值从另一个寄存器的值中减去,结果存储在目标寄存器中。
    SUB rd, rs1, rs2  # rd = rs1 - rs2
    
  • ADDI: 将一个立即数与寄存器的值相加,结果存储在目标寄存器中。
    ADDI rd, rs1, imm  # rd = rs1 + imm
    

逻辑指令

  • AND: 对两个寄存器的值执行按位与操作,结果存储在目标寄存器中。
    AND rd, rs1, rs2  # rd = rs1 & rs2
    
  • OR: 对两个寄存器的值执行按位或操作,结果存储在目标寄存器中。
    OR rd, rs1, rs2  # rd = rs1 | rs2
    
  • XOR: 对两个寄存器的值执行按位异或操作,结果存储在目标寄存器中。
    XOR rd, rs1, rs2  # rd = rs1 ^ rs2
    
  • ANDI: 将寄存器的值与一个立即数进行按位与操作,结果存储在目标寄存器中。
    ANDI rd, rs1, imm  # rd = rs1 & imm
    

移位指令

  • SLL: 将寄存器的值左移指定的位数,结果存储在目标寄存器中。
    SLL rd, rs1, rs2  # rd = rs1 << rs2
    
  • SRL: 将寄存器的值右移指定的位数,结果存储在目标寄存器中(逻辑右移)。
    SRL rd, rs1, rs2  # rd = rs1 >> rs2
    
  • SRA: 将寄存器的值右移指定的位数,结果存储在目标寄存器中(算术右移)。
    SRA rd, rs1, rs2  # rd = rs1 >> rs2 (arithmetic)
    

比较指令

  • SLT: 如果第一个寄存器的值小于第二个寄存器的值,则目标寄存器设置为1,否则设置为0(有符号比较)。
    SLT rd, rs1, rs2  # rd = (rs1 < rs2)
    
  • SLTU: 如果第一个寄存器的值小于第二个寄存器的值,则目标寄存器设置为1,否则设置为0(无符号比较)。
    SLTU rd, rs1, rs2  # rd = (rs1 < rs2) (unsigned)
    
  • SLTI: 如果寄存器的值小于立即数,则目标寄存器设置为1,否则设置为0(有符号比较)。
    SLTI rd, rs1, imm  # rd = (rs1 < imm)
    

控制流指令

条件分支指令

  • BEQ: 如果两个寄存器的值相等,则跳转到目标地址。
    BEQ rs1, rs2, offset  # if (rs1 == rs2) PC += offset
    
  • BNE: 如果两个寄存器的值不相等,则跳转到目标地址。
    BNE rs1, rs2, offset  # if (rs1 != rs2) PC += offset
    
  • BLT: 如果第一个寄存器的值小于第二个寄存器的值,则跳转到目标地址(有符号比较)。
    BLT rs1, rs2, offset  # if (rs1 < rs2) PC += offset
    
  • BGE: 如果第一个寄存器的值大于或等于第二个寄存器的值,则跳转到目标地址(有符号比较)。
    BGE rs1, rs2, offset  # if (rs1 >= rs2) PC += offset
    

无条件跳转指令

  • JAL: 跳转到目标地址,并将返回地址存储在目标寄存器中。
    JAL rd, offset  # rd = PC + 4; PC += offset
    
  • JALR: 跳转到由寄存器和立即数计算出的地址,并将返回地址存储在目标寄存器中。
    JALR rd, rs1, offset  # rd = PC + 4; PC = (rs1 + offset) & ~1
    

内存访问指令

加载指令

  • LW: 从内存中加载一个字(32位)到目标寄存器。
    LW rd, offset(rs1)  # rd = *(rs1 + offset)
    
  • LH: 从内存中加载一个半字(16位)到目标寄存器,并进行符号扩展。
    LH rd, offset(rs1)  # rd = *(int16_t *)(rs1 + offset)
    
  • LHU: 从内存中加载一个半字(16位)到目标寄存器,并进行零扩展。
    LHU rd, offset(rs1)  # rd = *(uint16_t *)(rs1 + offset)
    
  • LB: 从内存中加载一个字节(8位)到目标寄存器,并进行符号扩展。
    LB rd, offset(rs1)  # rd = *(int8_t *)(rs1 + offset)
    
  • LBU: 从内存中加载一个字节(8位)到目标寄存器,并进行零扩展。
    LBU rd, offset(rs1)  # rd = *(uint8_t *)(rs1 + offset)
    

存储指令

  • SW: 将一个字(32位)从源寄存器存储到内存中。
    SW rs2, offset(rs1)  # *(rs1 + offset) = rs2
    
  • SH: 将一个半字(16位)从源寄存器存储到内存中。
    SH rs2, offset(rs1)  # *(int16_t *)(rs1 + offset) = rs2
    
  • SB: 将一个字节(8位)从源寄存器存储到内存中。
    SB rs2, offset(rs1)  # *(int8_t *)(rs1 + offset) = rs2
    

这些指令构成了 RISC-V 基础指令集的重要部分,为各种计算和控制流操作提供了必要的功能。