csr赛车t2(我们一起学RISC-V——05-RV32I指令集)
更新时间:2022-10-14 11:04:26本期内容如下:
- RISC-V指令格式
- RV32I指令命名规则
- RV32I指令集
- 重点指令详解
一、RISC-V指令格式
RISC-V按照32bit的指令不同字符的具体分布共分为6种基本格式,分别是R类型,I类型,S类型,U类型,J类型,B类型。具体32bit的数据功能划分如图1所示。
- R类型——寄存器间操作指令;
- I类型 ——短立即数和访存Load操作指令;
- S类型——访存Store操作指令;
- U类型——用于操作长立即数的指令;
- J类型——用于无条件跳转的指令;
- B类型——用于有条件跳转的指令;
在图1中rd为目标寄存器;rs1,rs2为源寄存器1,2;imm[11:0]为12位立即数。opcode和func3共同决定了不同类型的指令;
二、RV32I指令命名规则
图2 位RV32I指令集的全称,在图2中有下划线"_"的部分为指令的关键词,中括号为可选组合部分,单独的"_"表示什么也不加,举个例子:
- add在RISC-V中是一个加法指令,该指令是一个R类型的操作指令参见图1,该指令还有一个立即数操作(I类型)的版本也就是addi。
add a0,a1,a2 //这是一个将寄存器a1和a2相加,之后把结果保存到a0中的指令
addi a0,a1,12 //这是一个将寄存器a1和立即数12相加,之后再把结果保存到a0中的指令
- and为“逻辑与”指令,该指令是一个R类型的操作指令,该指令也有一个立即数操作(I类型)的版本也就是andi。
and t0,t1,t2 //这是一个将寄存器a1和a2按位相与,之后把结果保存到t0中的指令
andi t0,t1,0x01 //这是一个将寄存器t1和立即数0x01相与,之后再把结果保存到t0中的指令
其他指令可以参照图2,进行理解学习。
三、RV32I指令集
本部分暂时仅介绍机器指令,由于很多伪指令容易让学习者混淆一些概念,和编译器相关的伪指令将在今后介绍。
在寄存器功能表述中rs1,rs2,rd均表示寄存器的名称,(rs1)表示rs1寄存其中的数值,
(rs2)表示rs2寄存其中的数值,(rd)表示rd寄存其中的数值,其他寄存器的表述(rx)表示rx寄存器中的数值。
M(xxxx)表示内存地址xxxx的数值。
3.1 算术运算
本部分将介绍加法指令add 、addi和减法指令sub
rd,rs1,rs2可以是RISC-V寄存器的X0~X31任意寄存器中的数据
- add rd , rs1, rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现(rd)=(rs1) (rs2),忽略算术溢出。
- addi rd, rs1, imm
rd为目标寄存器,rs1为源寄存器1,imm为立即数带有符号,该指令实现(rd)=(rs1) imm,忽略算术溢出。
- sub rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现(rd)=(rs1)-(rs2),忽略算术溢出。
3.2 逻辑运算
本部分将介绍逻辑运算
逻辑“与”and、andi;
逻辑“或”运算or、ori;
逻辑“异或”xor、xori
- and rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现按位“与”操作,即(rd)=(rs1)&(rs2)。
- andi rd, rs1, imm
rd为目标寄存器,rs1为源寄存器1,imm为立即数带有符号,该指令实现按位“与”,即(rd)=(rs1)&imm。
- or rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现按位或,即(rd)=(rs1)|(rs2)。
- ori rd, rs1, imm
rd为目标寄存器,rs1为源寄存器1,imm为立即数带有符号,该指令实现按位或,即(rd)=(rs1)|imm。
- xor rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现按位异或,
即(rd)=(rs1)^(rs2)。
- xori rd, rs1, imm
rd为目标寄存器,rs1为源寄存器1,imm为立即数带有符号,该指令实现按位异或,
即(rd)=(rs1)^imm。
3.3 移位操作
算术右移sra,srai:最高位填充符号位。正数填充0,负数填充1
逻辑右移srl,srli:最高位填充0
逻辑左移sll,slli:最高位补0
- sll rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现逻辑左移动,
即(rd)=(rs1)<<(rs2)。
- slli rd, rs1, shamt
rd为目标寄存器,rs1为源寄存器1,shamt为立即数,该指令实现立即数逻辑左移动,
即(rd)=(rs1)<<shamt。
- sra rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现算术右移动,
即(rd)=(rs1)>>rs2。
- srai rd, rs1, shamt
rd为目标寄存器,rs1为源寄存器1,shamt为立即数,该指令实现立即数算术右移动,
即(rd)=(rs1)>>shamt。
- srl rd,rs1,rs2
rd为目标寄存器,rs1为源寄存器1,rs2为源寄存器2,该指令实现逻辑右移动,
即(rd)=(rs1)<<(rs2)。
- srli rd, rs1, shamt
rd为目标寄存器,rs1为源寄存器1,shamt为立即数,该指令实现立即数逻辑右移动,
即(rd)=(rs1)>>shamt。
3.4 内存操作
内存加载指令主要是实现从内存地址读取数据到处理器寄存器(Load),存储寄存器中的数据到指定地址的内存单元中(Store)
- lui rd,imm
加载有符号立数到高20位,即imm到rd的高20bit,imm取值范围为0-1048575。
C伪代码表示为,(rd)=(imm<<12)&0xfff。
例如:
lui a0,0x23 //此时a0的数值为0x23000
- auipc rd,imm
加载有符号立即数imm的到PC寄存器高20位,同时保存结果到rd中,C伪代码表示为(rd)=(pc) (imm<<12)&0xfff。
例如:
auipc a1, 0x06 //假设当前pc数值为0x04,执行该指令后,a1的数值为0x6004
- lb rd,rs1,imm
rs1为立即数,rd为目标寄存器,imm为立即数,读取((rs1) imm)地址的一字节数据经符号扩展后保存到rd中。
(rd)=((rs1) imm)&0xff
该指令通常被写成lb rd,offset(rs),其中offset也就是立即数,否则gnu编译器不能识别。
- lbu rd,rs1,imm
rs1为立即数,rd为目标寄存器,imm为立即数,读取((rs1) imm)地址的一字节数据经零扩展后保存到rd中。
(rd)=((rs1) imm)&0xff
该指令通常被写成bu rd,offset(rs),其中offset也就是立即数,否则gnu编译器不能识别。
- lh rd,rs1,imm
rs1为立即数,rd为目标寄存器,imm为立即数,读取((rs1) imm)地址的两字节数据经符号扩展后保存到rd中。
rd=((rs1) imm)&0xffff
该指令通常被写成lh rd,offset(rs),其中offset也就是立即数,否则gnu编译器不能识别。
- lhu rd,rs1,imm
rs1为立即数,rd为目标寄存器,imm为立即数,读取((rs1) imm)地址的两字节数据经零扩展后保存到rd中。
rd=((rs1) imm)&0xffff
该指令通常被写成lhu rd,offset(rs),其中offset也就是立即数,否则gnu编译器不能识别。
- lw rd,rs1,imm
rs1为立即数,rd为目标寄存器,imm为立即数,读取((rs1) imm)地址的四字节数据经符号扩展后保存到rd中。
rd=((rs1) imm)&0xffffffff
该指令通常被写成lw rd,offset(rs),其中offset也就是立即数,否则gnu编译器不能识别。
- sb rs1,rs2,imm
rs1为目标地址寄存器,rs2为源寄存器,imm为立即数,读取rs2寄存器的一字节数据保存到地址((rs1) imm)地址中。
M((rs1) imm)=(rs2)&0xff
该指令通常被写成sb rs2,offset(rs1),其中offset也就是立即数,否则gnu编译器不能识别。
- sh rs1,rs2,imm
rs1为目标地址寄存器,rs2为源寄存器,imm为立即数,读取rs2寄存器的两字节数据保存到地址((rs1) imm)中。
M((rs1) imm)=(rs2)&0xffff
该指令通常被写成sh rs2,offset(rs1),其中offset也就是立即数,否则gnu编译器不能识别。
- sw rs1,rs2,imm
rs1为目标地址寄存器,rs2为源寄存器,imm为立即数,读取rs2寄存器的四字节数据保存到地址((rs1) imm)中。
M((rs1) imm)=(rs2)&0xffffffff
该指令通常被写成sw rs2,offset(rs1),其中offset也就是立即数,否则gnu编译器不能识别。
3.5 比较指令
比较指令主要用于比较两个寄存器的数值,以及寄存器和立即数的比较。
- slt rd, rs1, rs2
rd为目标寄存器,rs1为比较数1,rs2为比较数2, 本指令表示如果rs1中的数据比rs2中的数据小就设置rd为1,否则设置rd为0.rs1,rs2为有符号数。
用C伪代码表示如下:
if((rs1)<(rs2))
rd=1;
else
rd=0;
- slti rd,rs1,imm
rd为目标寄存器,rs1为比较数1,imm为比立即数, 本指令表示如果rs1中的数据比imm小就设置rd为1,否则设置rd为0..rs1,imm为有符号数。
用C伪代码表示如下:
if((rs1)<imm)
rd=1;
else
rd=0;
- sltu rd,rs1,rs2
rd为目标寄存器,rs1为比较数1,rs2为比较数2, 本指令表示如果rs1中的数据比rs2中的数据小就设置rd为1,否则设置rd为0.rs1,rs2被视为无符号数。
用C伪代码表示如下:
if((rs1)<(rs2))
rd=1;
else
rd=0;
- sltiu rd,rs1,imm
rd为目标寄存器,rs1为比较数1,imm为比较立即数。 本指令表示如果rs1中的数比立即数imm小就设置rd为1,否则设置rd为0。rs1,imm为被视为无符号数。
用C伪代码表示如下:
if((rs1)<imm)
rd=1;
else
rd=0;
3.6 控制和状态寄存器操作
本部分指令主要是为了操作处理器本身的一些控制和状态寄存器而设定的。
- csrrw rd,csr,rs1
rd为目标寄存器,csr为状态寄存器,rs1为源寄存器1,该指令为先读取csr寄存器的数据t,之后将rs1内的数据写入csr,最后再将t数据写入rd。
- csrrs rd,csr,rs1
rd为目标寄存器,csr为状态寄存器,rs1为源寄存器1,该指令为先读取csr寄存器的数据t,之后将rs1与csr按位“或”后的数据写入csr,最后再将t数据写入rd。
- csrrc rd,csr,rs1
rd为目标寄存器,csr为状态寄存器,rs1为源寄存器1,该指令为先读取csr寄存器的数据t,之后将rs1与csr按位“与”后的数据写入csr,最后再将t数据写入rd。
- csrrwi rd,csr,imm
rd为目标寄存器,csr为状态寄存器,imm为立即数,该指令先读取csr寄存器的数据并写入rd中,之后5bit零扩展的立即数写入csr。
- csrrci rd,csr,imm
rd为目标寄存器,csr为状态寄存器,imm为立即数,该指令先读取csr寄存器的数据t,之后将t与5bit零扩展的立即数imm位“与”后写入csr,再把t写入rd。
- csrrsi rd,csr,imm
rd为目标寄存器,csr为状态寄存器,imm为立即数,该指令先读取csr寄存器的数据t,之后与5bit零扩展的立即数imm位“或”后写入csr,再把t写入rd。
3.7 条件跳转指令
- beq rs1,rs2,imm
rs1比较数值1,rs2为比较数值2,imm为立即数,该指令表示当rs1和rs2数值相同时,设置pc数值为(pc) imm的,在这里imm就是offset地址偏移。
- bne rs1,rs2,imm
rs1比较数值1,rs2为比较数值2,imm为立即数,该指令表示当rs1和rs2数值不相同时,设置pc数值为(pc) imm的,在这里imm就是offset地址偏移。
- bge rs1,rs2,imm
rs1比较数值1,rs2为比较数值2,imm为立即数,该指令表示当rs1大于等于rs2数值时,设置pc数值为(pc) imm的,在这里imm就是offset地址偏移。
- blt rs1,rs2,imm
rs1比较数值1,rs2为比较数值2,imm为立即数,该指令表示当rs1小于rs2数值时,设置pc数值为(pc) imm的,在这里imm就是offset地址偏移。
- bgeu rs1,rs2,imm
rs1比较数值1,rs2为比较数值2,imm为立即数,该指令表示当无符号数rs1大于等于无符号数rs2数值时,设置pc数值为(pc) imm的,在这里imm就是offset地址偏移。
- bltu rs1,rs2,imm
rs1比较数值1,rs2为比较数值2,imm为立即数,该指令表示当无符号数rs1小于无符号数rs2数值时,设置pc数值为(pc) imm的,在这里imm就是offset地址偏移。
3.8 无条件跳转指令
- jal rd,imm
把rd的值设置为当前(pc) 4,pc的值设为pc当前数值 imm,imm为有符号扩展的立即数,imm也即是offset。
- jalr rd,rs1,imm
读取(pc) 4为t,把pc数值设为((rs1) imm并设置0bit为0),将t值保存到rd中, imm也即是offset。
该指令通常也被写为jalr rd,offset(rs1)
四、重点指令详解
在基本指令集中,如下指令需要认真理解其功能,这样可以防止今后的学习中,混淆概念。
- lui rd,imm
该指令所加载的imm立即数是一个20bit的数据,取值范围为0-1048575,rd只有高20bit用于保存imm数据,低12bit被清0了。
由于risc-v的立即数并不能32bit,实际中我们期望直接写一个32bit的常量数值到RISC-V的寄存器中,我们应该如何实现呢?
在risc-v的汇编指令格式中,U类型指令有20bit立即数,I类型指令有12bit立即数,我们可以借助相关类型的操作指令来完成,32bit常量数据的加载。
例如:
lui t0,(0x12345678>>12) //此时t0=0x12345000
addi t0,t0,(0x12345678&0xfff) //此时t0=0x12345000 0x678=0x12345678,这样我们就把0x12345678放到了t0中
看了上面的例子,有些同学可能会产生疑问,为啥我这么费劲呢,直接一条指令加载32bit不就可以了吗?想法是好的,但是RISCV没有这种功能的指令,如果有自然是可以的了。
上述代码通常也被写成如下形式:
lui t0,%hi(0x12345678) //此时t0=0x12345000,%hi()是编译器支持的求取32bit的高20bit的数值,
addi t0,t0,%lo(0x12345678) //此时t0=0x12345000 0x678=0x12345678,这样我们就把0x12345678放到了t0中
//%lo()是编译器支持的求取32bit的低12bit的数值,
- auipc rd,imm
该指令加载的立即数是一个20bit的数据,取值范围为0-1048575,但是该指令rd中保存的数据是
(pc) (立即数<<12)
例如:
//例1--------------------------
auipc a0,0 //如果pc当前值为0x18,执行该指令将a0数值=pc数值 0,该条指令通常用于读取pc当前数值。
//例2--------------------------
auipc t0,(0x12345678>>12) //t0数值=0x12345000 pc数值
addi t0,t0,(0x12345678&0xfff)//t0数值=0x12345000 pc数值 0x678=0x12345678 pc数值
//以上两条指令配合其jalr指令便可以实现从pc当前地址跳转到32bit的地址空间
jalr ra,0(t0) // ra数值当前pc数值 4,pc数值=t0=(0x12345678 pc数值)&~0x1,这就3条就实现了相对pc的
// 32bit地址空间的跳转
以上两条lui,auipc指令,仅仅是将数据保存到rd中,并不会对pc数值产生影响
3. jal rd,imm和jalr rd,rs1,imm
1) 这两条指令都会改变PC的数值,前者pc=pc当前值 imm,后者(pc)=((rs1) imm)&~0x1;
2) rd中保存的都是(pc) 4;
3)如将rd指定为ra(返回)寄存器,那么就可实现函数的跳转返回。
因为在调用指令跳转到子函数执行完毕后,在子程序中执行MRET等操作时,ra数据会被存入pc,从而实现了从子函数,返回继续执行程序。
4.beq,bne,bge,blt,bgeu,bltu
以上指令均未显示地对PC进行操作,但它们的执行终将影响pc的数值,pc的数值为当前(pc) imm。
相关推荐
- 最新资讯
-
- 2022-11-15 世界杯8分之一比赛比分(世界杯小历史,1990世界杯1/8决赛,艰难的胜利,普拉特漂亮一击)
- 2022-11-15 12年奥运会金牌哪个国家最多(世运会最终奖牌榜:中国第十,乌克兰第三,德国力压美国排名榜首)
- 2022-11-15 我对穆帅有种特殊的感情(纵你虐我千百遍,我仍待你如初恋!穆里尼奥:希望曼联早日复兴)
- 2022-11-15 菲律宾韩国街在哪里(韩国 | 九月初的济州岛,时有风,偶有雨)
- 2022-11-15 欧联杯冠军进欧冠什么时候(欧冠赛与欧联杯的区别,你知道多少?)
- 2022-11-15 为什么nba篮球员妻子都爱(为何科比的妻子那么受欢迎呢,十几个人追求?拥有三个魅力原因)
- 2022-11-15 5号篮球和7号篮球图(2022-2023赛季NBA每支球队的城市版球衣)
- 2022-11-15 花式运球有错吗(指责队友犯规,自己花式运球失误?郭艾伦的脾气决定辽篮上限)
- 2022-11-15 我想看霹雳赛车(嘲讽值拉满,魏国黑科技霹雳车,守九宫八卦能打赢满红吴骑)
- 2022-11-15 马内造红牌 破门(马内遭“爆头”仍坚持比赛15分钟并进球,球迷痛批塞内加尔换人不及时)
- 推荐攻略
-
-
乌克兰总统身亡(乌总统泽连斯基解除乌总检察长及国家安全局局长职务)
-
足球比赛每个半场多少分钟(足球比赛每半场几分钟)
-
2021中超今天哪里转播(今晚!中超2场对决,CCTV5 直播申花PK武汉,腾讯体育亚泰vs天津)
-
2022梅西坠机身亡事件结果(足坛变天!巴萨无缘榜首的2年:梅西告别,老马去世,2-8惨案)
-
2021全运会篮球直播赛程辽宁(4月22日央视直播:CBA总决赛;赵心童vs马奎尔,塞尔比vs颜丙涛)
-
中国最强导弹(世界洲际导弹前10排名,中国东风导弹领先美国,第一名堪称导弹王)
-
2021篮球比赛在哪里看(CCTV5直播NBA 辽篮争夺CBA总决赛冠军点 颜丙涛出战斯诺克世锦赛)
-
东航结果不敢公布了(民航局再次回应东航MU5735事故调查!查明原因有多难,多久公布?)
-