RISCV指令集分析
一、RV32I指令格式
RV32I一共有6种基本指令格式,如下图所示
其中S-type指令格式和B-type指令格式可以认为是同一种格式,因为两种格式都是用了立即数的12位,只不过S类型用的是0到11位而B类型用的是1到12位。
同理U指令格式和J指令格式也可以认为是同一种指令格式,U类型用的是立即数的12到31位而J类型用的是1到20位
二、各格式指令的介绍
1、I类型指令
addI rd rs1 immediate
寄存器x[rd] = x[rs1] + immediate。该立即数只有12位,根据RISCV的规定所有的立即数不足32的都进行符号扩展到32位
slti rd rs1 immediate
比较寄存器x[rs1]和立即数imm的值,根据比较结果设置寄存器x[rd]的值
sltiu rd rs1 immediate
和slti指令类似,只不过这里比较的立即数为无符号数
xori rd rs1 immediate
寄存器x[rd] = x[rs1] ^ sext[imm],sext[imm]中的sext其实就是sign-extend(符号扩展)的缩写表示将该立即数扩展到32位,如果是有符号数则进行符号扩展,若是无符号数则进行无符号扩展
ori和addi指令的意义类似于xori只不过一个是做或操作一个是做与操作
slli rd rs1 shamt
寄存器x[rd] = 寄存器x[rs1]逻辑左移shamt位
srli rd rs1 shamt
逻辑右移
srai rd rs1 shamt
算术右移
lw rd offset(rs1)
offset(rs1)表示的地址是 M[sext[offset] + x[rs1]] 也就是将offset符号扩展到32位然后加上寄存器x[rs1]的值,找到内存中的该地址取得一个字(w)也就是32位,存储到寄存器x[rd]中
lb,lh,lw,lbu,lhu都是从内存中加载数据到寄存器,其中lbu和lhu中的offset进行的是无符号扩展
3、R类型指令
add,sub,sll,slt,sltu,xor,srl,sra,or,and指令和上述的I形指令很多类型,不同的地方就是将立即数换成了寄存器rs2
4、S类型指令
sw rs2 , offset(rs1)
M[sext[offset] + x[rs1]] = 寄存器x[rs2] 将寄存器x[rs2]中的值存储到内存中,内存的寻址方式和I形lw指令一样
sh,sb指令也类似
5、B类型指令
bge rs1 rs2 offset
如果寄存器x[rs1]的值大于等于寄存器x[rs2]的值,则pc += sext[offset] ,pc的值进行更改也就是进行跳转
对应的bne,blt,beq,bltu,bgeu指令的含义都类似,不同的就是寄存器的比较方式不同,其中bltu和bgeu的offset扩展是无符号扩展
6、U形指令
lui rd imm
将立即数imm加载到寄存器x[rd]的高20位
auipc rd imm
向pc高位加上立即数
7、J形指令
jal rd offset
寄存器x[rd] = pc + 4,然后pc += sext[offset]
jalr rd rs1 offset(I形指令)
把 pc 设置为 x[rs1] + sign-extend(offset),把计算出的地址的最低有效位设为 0,并将原 pc+4 的值写入 x[rd]。rd 默认为 x1。