RISC-V指令集:开启新一代计算机时代

1、寄存器

RV32I有32个通用寄存器,以及一个PC寄存器。其中有一个通过硬件设置的值恒为 0 的 x0 寄存器

注:RISC-V的32个寄存器x0~x31是用0~31这些数字来表示。

2、基础指令

RISC-V有六种基本指令格式:

每个字段名称的含义:


  • opcode(操作码):指令的基本操作,这个缩写是它惯用名称。
  • rd: 目的操作寄存器,用来存放操作结果。
  • funct3: 一个另外的操作码字段。
  • rs1: 第一个源操作数寄存器。
  • rs2: 第二个源操作数寄存器。
  • funct7: 一个另外的操作码字段。
  • imm:立即数

  • 2.1、R 型指令

    字段:

    funct7 rs2 rs1 funct3 rd opcode
    7位 5位 5位 3位 5位 7位

    指令:

    示例:

    指令 示例 含义
    add add a0, a1, a2 a0 = a1 + a2
    sub sub a0, a1, a2 a0 = a1 – a2
    sll sll a0, a1, a2 a0 = a1 << a2 (低位补0)
    srl srl a0, a1, a2 a0 = a1 >> a2(高位补0)
    sra sra a0, a1, a2 a0 = a1 >> a2 (算术右移,高位补原来的符号位)
    slt slt a0, a1, a2 a1 < a2 ? 1 : 0
    xor xor a0, a1, a2 a0 = a1 ^ a2
    or or a0, a1, a2 a0 = a1 | a2
    and and a0, a1, a2 a0 = a1 & a2

    2.2、I 型指令

    字段:

    imm rs1 funct3 rd opcode
    12位 5位 3位 5位 7位

    指令:

    示例:

    指令 示例 含义
    addi add a0, a1, 0x50
    slli slli a0, a1, 5 a0 = a1 << 5 (低位补0)
    srli srli a0, a1, 5 a0 = a1 >> 5 (高位补0)
    srai sra a0, a1, 5 a0 = a1 >> 5 (高位补原来的高位)
    slti slti a0, a1, 0x50 a1 < 0x50 ? 1 : 0
    xori xor a0, a1, 0x50 a0 = a1 ^ 0x50
    ori ori a0, a1, 0x50 a0 = a1
    andi andi a0, a1, 0x50 a0 = a1 & 0x50

    取值指令—Load

    字段:

    imm rs1 funct3 rd opcode
    12位 5位 3位 5位 7位

    指令:

    示例:

    lb x10,  0(x1)  //将x1的值加上0,将这个值作为地址, 取出这个地址所对应的内存中的值, 将这个值赋值给x10(取出的是8位数值)
    lh x10,  0(x1)  //从内存中取出16位数值
    lw x10, 0(x1)  //从内存中取出32位数值
    lbu x10, 0(x1) //从内存中取出8位无符号数值
    lhu x10, 0(x1) //从内存中取出16位无符号数值
    

    2.3、S 型指令

    字段:

    imm[11:5] rs2 rs1 funct3 imm[4:0] opcode
    7位 5位 5位 3位 5位 7位

    指令:

    示例:

    sb  x10, 0(x1)  //x1的值加上0,将这个值作为地址, 将x10的值存储到上述地址所对应的内存中去 (只会将x10的值的低8位写入)
    sh  x10, 0(x1)  //只会将x10的值的低16位写入
    sw  x10, 0(x1)  //只会将x10的值的低32位写入
    

    2.4、B 型指令

    字段:

    imm[12] imm[10:5] rs2 rs1 funct3 imm[4:1] imm[11] opcode
    1位 6位 5位 5位 3位 4位 1位 7位

    指令:

    指令 示例 含义 备注
    beq beq a1, a2, Lable if(a1 == a2){goto Label;} Lable是任意自定义的标签
    bne bne a1, a2, Lable if(a1 != a2){goto Label;}
    blt blt a1, a2, Lable if(a1 < a2){goto Label;}
    bgt bgt a1, a2, 100 if(a1 > a2){goto Label;} 100与Label对应着相同的指令, 实际上在运行时Label会变成pc+xxx
    bge bge a1, a2, 100 if(a1 <= a2){goto Label;}
    ble ble a1, a2, 100 if(a1 >= a2){goto Lable;}

    2.5、U 型指令

    字段:

    imm[31:12] rd opcode
    10位 5位 7位

    指令:

    lui  x10, 0x65432 //得到立即数的高20位,低位补0,立即数范围为:0x00~0xFFFFF
    

    2.6、J 型指令

    字段:

    imm[20] imm[10:1] imm[11] imm[19:12] rd opcode
    1位 10位 1位 8位 5位 7位

    指令:

    示例:

    jal ra, symbol   // 跳转到Symbol中去, 并把ra设置成返回地址 Symbol 可以是自定义的Label ,也可以是某个函数名
    jal ra, 100        // 跳转到pc + 100 * 2的地方中去, 并把ra设置成返回地址  pc相对寻址,对应的是位置无关代码(PIC)
    jalr ra, 40(x10) //跳转到x10+40 的地方中去, 并把ra设置成返回地址x10+40必须是绝对地址,指向内存中某个确定的地方(往往是函数的开头),非PIC
    

    3、汇编语言翻译成机器语言

    示例1:


    例题

    对于符号表示为:

    add x9, x20, x21

    的RISC-V指令,首先以十进制表示,然后用二进制表示

    答案

    有上面的介绍可知add指令的字段如下:

    直接用十进制表示如下:

    funct7 rs2 rs1 funct3 rd opcode
    0 21 20 0 9 51

    一条指令的每一段称为一个宇段。

    第一、第四和第六个字段(0、0 和 51)组合起来告诉RISC-V计算机该指令执行加法操作。

    第二个字段给出了作为加法运算的第二个源操作数的寄存器编号(21 表示 x21),

    第三个字段给出了加法运算的另一个源操作数(20代表×20)。

    第五个字段存放要接收总和的奇存器编号(9代表x9)。

    因此,该指令将寄存器 x20 和寄存器 x21 相加并将和存放在寄存器x9中。

    用二进制表示如下:

    funct7 rs2 rs1 funct3 rd opcode
    0000000 10101 10100 000 01001 0110011

    总上,add x9, x20, x21 的RISC-V指令对应的机器码为: 00000001010110100000010010110011


    示例2


    例题

    有以下几条汇编:

    ld x9, 240(x10)
    add x9, x21, x9
    addi x9, x9, 1
    sd x9, 240(x10)
    

    将它们翻译为对应的机器码

    答案

    🏄 自己尝试解答一下 🏄


    物联沃分享整理
    物联沃-IOTWORD物联网 » RISC-V指令集:开启新一代计算机时代

    发表评论