指令集解释
(规定:R[r]表示通用寄存器r的内容,M[addr]表示存储单元addr的内容,SEXT[imm]表示对imm进行符号扩展,ZEXT[imm]表示对imm进行零扩展)
整数运算类
-U型指令
lui rd,imm20:将该立即数存到寄存器rd的高20位,低12位为0
auipc rd,imm20:将20位的立即数加到PC的高20位上,结果存入rd
(auipc x10,0可以获取当前PC的内容,并存入x10中,因为这个立即数为0,所以就是把PC值加到x10上,获取PC的内容)
-I型指令(均含i,i表示一个操作数为立即数)
addi rd,rs1,imm12:将12位的立即数imm12符号扩展到32位(因为是符号扩展,就是在立即数的前面加上20个符号位),再+rs1中内容,结果放在rd。(这个指令可以直接加一个负数)
附:addi指令和lui指令结合可以对一个32位变量初赋值,无法在RISC v指令中直接给出一个32位立即数,需要将常数分解为两个立即数,先装高20位,再对低12位进行符号扩展,加到那20位上
slli rd,rs1,shamt(shamt是20~24位,是立即数,五位,32个,可以存放左移位数)将rs1的内容左移shamt位之后存到rd中。
(左移可以通过寄存器、立即数方式指定位数,但只有逻辑左移,因为逻辑左移和算术左移的结果相同,只有一个就行;
右移的话有高位补0和高位补符号两种,所以需要两种右移指令,位数指定也是两种方法)
一个例子 P118的例4.3 挺不错的 和别人讨论讨论
slti/sltiu rd,rs1,imm12:imm12都采用符号扩展,扩展后和rs1中的内容进行比较(无符号和有符号的情况不同吧?),小于——1存入rd,否则,0存入rd
控制转移类
-分支指令(都是B型指令
beq/bne/blt/bge/bltu/bgeu:rs1与rs2的内容满足条件,就跳转到目标处,否则依次执行下一条
(注:转移目标地址采用相对寻址方式,为指令中的立即数(偏移量)*2,就是左移一位,不过不太明白为啥指令宽度是4,指令地址最低位就是0)
-跳转指令
jal rd,imm20(J型指令):跳转到目标地址,并把不跳转时将要执行的指令地址(返回地址)存到存储器中
转移目标地址偏移量是imm20左移一位并进行符号扩展,基准是PC;并把PC+4(返回地址)保存到rd。
(如果将返回地址保存到x1,则可以实现过程调用,如果rd是x0,则可以实现无条件跳转,因为x0是0位寄存器,值恒为0且不能更改)
jalr rd,rs1,imm12:PC=rs1的内容+imm12扩展后的数,PC+4的值存到rd
jalr x0,x1,0 可以实现过程调用的返回(叠buff)
存储器访问指令
load相关:(rs1寄存器内容+imm12进行32位扩展后的数)的存储器的内容放到rd寄存器中。
带符号不足32位的,按符号扩展为32位;无符号不足32位的,按0扩展为32位后,放入rd。
store相关:rs2寄存器的内容放到(rs1寄存器内容+imm12进行32位扩展后的数)的存储器内容中,小端存放(从低位开始放)