1. 背景介紹
????????指令集從本質(zhì)上可以分為復(fù)雜指令集(Complex Instruction Set Computer,CISC)和精簡(jiǎn)指令集(Reduced Instruction Set Computer,RISC)兩種。復(fù)雜指令集的特點(diǎn)是能夠在一條指令內(nèi)完成很多事情。
????????指令架構(gòu)(Instruction Set Architecture, 縮寫(xiě)為ISA),是軟件和硬件的接口,不同的應(yīng)用需求,會(huì)有不同的指令架構(gòu)。
????????RISC-V的不同尋常之處在于:和幾乎所有以往的ISA不同,它是模塊化的。它的核心是一個(gè)名為RV32I的基礎(chǔ)ISA,運(yùn)行一個(gè)完整的軟件棧。RV32I是固定的,永遠(yuǎn)不會(huì)改變。這為編譯器編寫(xiě)者,操作系統(tǒng)開(kāi)發(fā)人員和匯 編語(yǔ)言程序員提供了穩(wěn)定的目標(biāo)。模塊化來(lái)源于可選的標(biāo)準(zhǔn)擴(kuò)展,根據(jù)應(yīng)用程序的需要, 硬件可以包含或不包含這些擴(kuò)展。這種模塊化特性使得RISC-V具有了袖珍化、低能耗的特點(diǎn)。
2. RISC-V指令格式
常見(jiàn)的RISC-V指令集如下表所示:
基本指令集 | 含義 |
RV32I | 32位整數(shù)指令集 |
RV32E | RV32I的子集,用于小型嵌入式場(chǎng)景 |
RV64I | 64位整數(shù)指令集,兼容RV32I |
RV128I | 128位整數(shù)指令集,兼容RV64I和RV32I |
RISC-V有六種基本指令格式:
- R-type:用于寄存器-寄存器操作
- I-type:用于短立即數(shù)和訪存 load 操作
- S-type:用于訪存 store 操作
- B-type:用于條件跳轉(zhuǎn)操作
- U-type:用于長(zhǎng)立即數(shù)
- J-type:用于無(wú)條件跳轉(zhuǎn)
????????指令只有6種格式,并且所有指令都是32位長(zhǎng),指令的低7位固定為opcode,簡(jiǎn)化了指令解碼。在RISC-V中對(duì)于所有指令,要讀寫(xiě)的寄存器的標(biāo)識(shí)符總是在同一位置,意味著在解碼指令之前,就可以先開(kāi)始訪問(wèn)寄存器,這些格式的立即數(shù)字段總是符號(hào)擴(kuò)展,符號(hào)位總是在指令中最高位,各種類型的指令構(gòu)成如下圖所示:
字段含義:
- opcode(操作碼):指令的基本操作,這個(gè)縮寫(xiě)是它慣用名稱。
- rd:目的操作寄存器,用來(lái)存放操作結(jié)果。
- funct3:一個(gè)另外的操作碼字段。
- rs1:第一個(gè)源操作數(shù)寄存器。
- rs2:第二個(gè)源操作數(shù)寄存器。
- funct7:一個(gè)另外的操作碼字段。
- imm:立即數(shù)
2.1. R型指令
32bit R型指令包括6個(gè)部分:
- opcode是操作碼,位寬7bit,在指令的0-6bit;
- rd (Destination Register)是目的寄存器,位寬5bit,在指令的7-11bit;
- funct3+funct7是兩個(gè)操作字段。funct3占了3bit,funct7占了7bit;
- rs1 (Source Register 1)是第一個(gè)源操作數(shù)寄存器,位寬5bit,在指令的15-19bit;
- rs2 (Source Register 2)是第二個(gè)源操作數(shù)寄存器,位寬5bit,在指令的25-31bit。
R型指令構(gòu)成如下:
R型的全部指令(RV32I)
R型指令包括加法、減法、邏輯運(yùn)算、移位運(yùn)算。
示例:
add a0, a1, a2 //a0 = a1 + a2
sub a0, a1, a2 //a0 = a1 - a2
sll a0, a1, a2 //a0 = a1 << a2(低位補(bǔ)0)
srl a0, a1, a2 //a0 = a1 >> a2(高位補(bǔ)0)
sra a0, a1, a2 //a0 = a1 >> a2 (算術(shù)右移,高位補(bǔ)原來(lái)的符號(hào)位)
slt a0, a1, a2 //a1 < a2 ? a0 = 1 : a0 = 0
xor a0, a1, a2 //a0 = a1 ^ a2
or a0, a1, a2 //a0 = a1 | a2
and a0, a1, a2 //a0 = a1 & a2
2.2. I型指令
I型指令包括5個(gè)部分:
- opcode是操作碼,位寬7bit,在指令的0-6bit;
- rd (Destination Register)是目的寄存器,位寬5bit,在指令的7-11bit;
- funct3是操作字段。funct3占了3bit,在指令的12-14bit;
- rs1 (Source Register 1)是第一個(gè)源操作數(shù)寄存器,占了5bit,在指令的15-19bit;
- 存放12位的立即數(shù)——imm[11:0],在指令的20-31bit。
I型指令構(gòu)成如下:
I型的全部指令(RV32I)
I型指令包括立即數(shù)的運(yùn)算和load指令。?
示例:
addi a0, a1, 0x5 //a0 = a1 + 0x5
subi a0, a1, 0x05 //a0 = a1 - 0x05
slli a0, a1, 0x05 //a0 = a1 << 0x05(低位補(bǔ)0)
srli a0, a1, 0x05 //a0 = a1 >> 0x05(高位補(bǔ)0)
srai a0, a1, 0x05 //a0 = a1 >> 0x05 (算術(shù)右移,高位補(bǔ)原來(lái)的符號(hào)位)
slti a0, a1, 0x05 //a1 < 0x05 ? a0 = 1 : a0 = 0
xori a0, a1, 0x05 //a0 = a1 ^ 0x05
ori a0, a1, 0x05 //a0 = a1 | 0x05
andi a0, a1, 0x05 //a0 = a1 & 0x05
示例:
lb x10, 0(x1) //將x1的值加上0,將這個(gè)值作為地址, 取出這個(gè)地址所對(duì)應(yīng)的內(nèi)存中的值, 將這個(gè)值賦值給x10(取出的是8位數(shù)值)
lh x10, 0(x1) //從內(nèi)存中取出16位數(shù)值
lw x10, 0(x1) //從內(nèi)存中取出32位數(shù)值
lbu x10, 0(x1) //從內(nèi)存中取出8位無(wú)符號(hào)數(shù)值
lhu x10, 0(x1) //從內(nèi)存中取出16位無(wú)符號(hào)數(shù)值
2.3. S型指令
S型指令包括6個(gè)部分:
- opcode是操作碼,位寬7bit,在指令的0-6bit;
- imm[4:0]+imm[11:5];
- funct3是操作字段。funct3占了3bit,在指令的12-14bit;
- rs1 (Source Register 1)是第一個(gè)源操作數(shù)寄存器,占了5bit,在指令的15-19bit;
- rs2 (Source Register 2)是第二個(gè)源操作數(shù)寄存器,占了5bit,在指令的25-31bit。
S型指令構(gòu)成如下:
S型的全部指令(RV32I)
S型指令包括store指令。?
示例:
sb x10, 0(x1) //x1的值加上0,將這個(gè)值作為地址, 將x10的值存儲(chǔ)到上述地址所對(duì)應(yīng)的內(nèi)存中去 (只會(huì)將x10的值的低8位寫(xiě)入)
sh x10, 0(x1) //只會(huì)將x10的值的低16位寫(xiě)入
sw x10, 0(x1) //只會(huì)將x10的值的低32位寫(xiě)入
2.4. B型指令
B型指令包括6個(gè)部分:
- opcode是操作碼,位寬7bit,在指令的0-6bit;
- imm[4:1]+imm[11]+imm[10:5]+imm[12];(注:imm[0]被丟棄,因?yàn)樗冀K為零)
- funct3是操作字段。funct3占了3bit,在指令的12-14bit;
- rs1 (Source Register 1)是第一個(gè)源操作數(shù)寄存器,占了5bit,在指令的15-19bit;
- rs2 (Source Register 2)是第二個(gè)源操作數(shù)寄存器,占了5bit,在指令的25-31bit。
B型指令構(gòu)成如下:
B型的全部指令(RV32I)
B型指令包括條件跳轉(zhuǎn)指令。?
示例:
beq a1,a2,Label //if(a1==a2){goto Label;}
bne a1,a2,Label //if(a1!=a2){goto Label;}
blt a1,a2,Label //if(a1< a2){goto Label;}
bgt a1,a2,Label //if(a1> a2){goto Label;}
bge a1,a2,Label //if(a1<=a2){goto Label;}
ble a1,a2,Label //if(a1>=a2){goto Label;}
2.5. U型指令
U型指令包括3個(gè)部分:
- opcode是操作碼,位寬7bit,在指令的0-6bit;
- rd (Destination Register)是目的寄存器,占了5bit,在指令的7-11bit;
- imm[31:12]:存放高20位的立即數(shù)——imm[31:12],在指令的12-31bit。
U型指令構(gòu)成如下:
U型的全部指令(RV32I)
示例:
lui x10, 0x65432 //得到立即數(shù)的高20位,低位補(bǔ)0,立即數(shù)范圍為:0x00~0xFFFFF
2.6. J型指令
J型指令包括3個(gè)部分:
- opcode是操作碼,位寬7bit,在指令的0-6bit;
- rd (Destination Register)是目的寄存器,占了5bit,在指令的7-11bit;
- 立即數(shù)劃分:imm[19:12]+imm[11]+imm[10:1]+imm[20]:
J型指令構(gòu)成如下:
J型的全部指令(RV32I)
示例:
jal ra, symbol // 跳轉(zhuǎn)到Symbol中去, 并把ra設(shè)置成返回地址 Symbol 可以是自定義的Label ,也可以是某個(gè)函數(shù)名
jal ra, 100 // 跳轉(zhuǎn)到pc + 100 * 2的地方中去, 并把ra設(shè)置成返回地址 pc相對(duì)尋址,對(duì)應(yīng)的是位置無(wú)關(guān)代碼(PIC)
jalr ra, 40(x10) // 跳轉(zhuǎn)到x10+40 的地方中去, 并把ra設(shè)置成返回地址x10+40必須是絕對(duì)地址,指向內(nèi)存中某個(gè)確定的地方(往往是函數(shù)的開(kāi)頭),非PIC
3. 通用寄存器
RV32I有32個(gè)通用寄存器,以及一個(gè)PC寄存器。其中有一個(gè)通過(guò)硬件設(shè)置的值恒為 0 的 x0 寄存器
注:RISC-V的32個(gè)寄存器x0~x31是用0~31這些數(shù)字來(lái)表示。
參考文檔、博客:
RISC-V官方文檔
riscv指令集基礎(chǔ)_konghhhhh的博客-CSDN博客
計(jì)算機(jī)系統(tǒng)基礎(chǔ)(五)之RISC-V指令集_riscv指令集_深度學(xué)習(xí)的學(xué)習(xí)僧的博客-CSDN博客文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-621039.html
RISC-V指令集_riscv指令集_點(diǎn)燈大師~的博客-CSDN博客文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-621039.html
到了這里,關(guān)于RISC-V 指令集介紹的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!