RISC V RV32I 基本6種指令集

2021-10-04 22:45:11 字數 3299 閱讀 8734

本文是參考文件:the risc-v instruction set manual volume i: unprivileged isa document version 20191213

非常的規整,可以看到rs1和rs2都作為資料來源暫存器,同時rd一直作為目標暫存器。然後這三個暫存器在6種型別指令中的位置是固定的!這使得硬體解碼非常簡單。

立即數的最高位一直在最左邊,這方便了做符號位的拓展。

相比與arm,將指令放不下的立即數放進常量池然後用load去讀。risc v用的是兩條指令,先用u type讀高20位的資料,然後再用加法加上低12位。這使得不用去訪問外部儲存也能處理高位寬的常數。

立即數預設都是有符號數的,都需要符號拓展。

b型別和s型別的差別,是b的立即數是s的立即數*2,但是為了保證第2個特點,同時保持最多的位的位置保持不變,比如指令的6到11位,僅僅改變了第6位從s的imm[0]變為imm[11]。這也是方便了硬體解碼,但是苦逼了編譯器。

u型別和j型別同第五點。

講多乙個,常用暫存器有乙個x0,他的值一直為0,這個當你指令不需要乙個暫存器就用它,或者用x0實現一些特殊的指令,比如addi x0, x0, 0,就是啥也不幹。

整體就是暫存器-立即數用i型別指令,暫存器-暫存器用r型別指令。

暫存器-立即數運算

比如addi rd, rs1, imm:就是reg[rd] = reg[rs1] + $signed(imm);

slti (set less than immediate) rd, rs1, imm:就是當reg[rs1]比$signed(imm)小的時候,reg[rd]為1,否則為0,有符號比較。

sltiu跟slti差不多,不過是無符號數比較。

andi, ori, xori是邏輯操作,(有符號數)。andi rd, rs1, imm:reg[rd] = reg[rs1] & imm

移位操作也是編譯成i type的。移位的位數是imm[4:0],所以一次指令最多可以移動32位,跟暫存器的位寬一樣。

slli:是邏輯左移,低位補零

srli:是邏輯右移, 高位補零

srai:是算術右移,高位補原來高位。

(這裡我有個問題,原文是說the right shift type is encoded in bit 30,所以按說應該右移型別的第30位應該是1,左移是0吼,但又好像不太是。anyway)

lui (load upper immediate): lui rd imm。就是reg[rd] [31:12] = imm。reg[rd] [11:0] = 0。就是把imm賦給rd的高20位,然後低12位補零。一般後面加乙個addi的指令,把低12位的值給上。這樣子,通過兩條指令,就把乙個32位的imm賦給了暫存器啦。

auipc (add upper immediate to pc):就是在lui的基礎上,再加上這個命令的pc位址。同樣後面再加乙個12位的加法,就可以定址到任何位置的指令的位址啦。

整數的暫存器-暫存器運算指令

這種就比較簡單了,都是把rs1,rs2暫存器裡面的值運算一下,然後將結果給rd就完事了。

add就是加,sub就是減,都不考慮溢位的哦。

slt和sltu分別是有符號比較和無符號數比較,rs1控制指令就是if else這種分支跳轉的指令了,這個玩意複雜可以很複雜,我這裡就是簡單介紹一下指令。

非條件跳轉

jal:就是pc指標跳轉到當前位置加上,這是j型,你軟體給說jal rd 16,其實實現的是pc = pc + 32。然後將pc + 4這個值賦給rd存放好到時候要返回來的位址。imm是2個位元組對齊的,20位就是2mb的定址空間了,imm有符號數的哦。

jalr功能跟jal差不多,比如jalr rd rs1 imm,那就是pc = reg[rs1] +imm。然後把最低有效的位置0。

條件跳轉指令

所有的條件跳轉都是b型別的指令。b型別的imm都是2位元組對齊的。

beq and bne分別當rs1和rs2相等和不相等時,跳轉。否則就不跳。

blt and bltu 分別是有符號數比較和無符號數比較,當rs1=rs2時候就跳,否則不跳

再強調哦,跳轉分支我這裡只是說明一下指令,具體有一些**分支啊,應用啊,link啊啥的。

load and store 指令

risc v的load 和store指令也是乙個特色哦,就是load和store只能通過暫存器來操作,就是一定要把位址放在在暫存器裡面,然後load這個暫存器的位址讀取memory裡面的資料。

load從mem讀取乙個32位的資料到rd。位址是reg[rs1] + imm

store 是把rs2裡面的資料放到位址是reg[rs10] + imm

lh 從mem讀取乙個16位的資料,然後符號拓展到32位,再放到rd中

lhu 從mem讀取乙個16位的資料,然後高位補0到32位,再放到rd中

lb and lbu 同理處理8位的資料

sw, sh, and sb同理分別sore 32,16,8位的資料。

rv32i是risc v最基本的指令集型別,還有一些低功耗的呀,高效能的呀啥的,rv32i指令集的特點是特別規整,這加大了額外的編輯器的工作量,比如b指令啥的,但是卻簡化的硬體設計,應該還是非常值得的呀。rv32i一共有40條指令,我這裡一共介紹了33條指令,後面還有一些memory order,environment call and breakpoints,hint的,稍稍複雜,怕講的太誤人了。我這裡也不一定正確,請多指教。

stm32f103rbt6基本介紹

stm32f103rbt6 主頻最高可以達到72mhz。r 64腳 b 128k位元組的快閃儲存器儲存器 中容量產品 問題6 裡面gpioc odr 1 8 是什麼?回答6 這個操作實際上就是把gpioc裡的odr暫存器的第八位取反,其他位不變。是異或符號,如果大家不懂什麼是異或的話應該好好學學c語...

C 八種基本排序 堆排序(6)

知識擴充 完全二叉樹的特點 從作為第一層的根開始,除了最後一層之外,第n層的元素個數都必須是2的n次方 第一層2個元素,第二層4個,第三層8個,以此類推。每一行的元素都從最左邊開始安放 生成的順序是從上往下,從左往右 兩個元素之間不能有空閒 堆的性質 小根堆與大根堆的定義 堆排序原理 堆頂元素 即二...

STM32F103韌體庫程式設計(6) I2C

brief iic eeprom 配置,工作引數配置 param 無 retval 無 void i2c ee config void 向eeprom寫入乙個位元組 void eeprom byte write uint8 t addr,uint8 t data 向eeprom寫入多個位元組 頁寫入...