iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0
Software Development

RISC-V 與處理器之架構學習及應用系列 第 5

[Day05] RISC-V Instructions (3/3)

  • 分享至 

  • xImage
  •  

本章小目錄
一~六:Control
七:Miscellaneous
八:Extensions
九:Summary

一、Control Instructions(控制指令)

  1. 用來指定下一行 code 該執行哪裡,而不是按順序執行。
  2. Control Instructions 有兩種:
    • Conditional jumps(條件跳轉):只有滿足特定條件時才跳轉到指定 code。
    • Unconditional jumps(無條件跳轉):不論任何條件,直接跳轉到指定 code。
  3. 範例bne x5, x0, Label,意思是如果x5和x0不相等,跳轉到 Label 行執行 code;否則繼續執行下一行。

二、Labels

  1. 是控制指令中人類可讀的標識,用來標記某行 code。
  2. 範例:
            addi x5, x0, 0
            addi x6, x0, 10
    Loop:   add x5, x5, x6
            addi x5, x5, -1
            bne x5, x0, Loop
    
    這裡Loop是 Labels,用於控制跳轉。

三、Types of Branches(分支類型)

  1. beq:當兩個 register 的值相等時跳轉。
  2. bne:當兩個 register 的值不相等時跳轉。
  3. blt, bge, bltu, bgeu:比較小於和大於等於,適用於帶符號和無符號數字。
  4. 注意:沒有bgt指令,若需要bgt可使用blt將比較對象對調來實現。
  5. 範例
    • beq (Branch if Equal)
      • 當兩個寄存器的值相等時,跳轉到標籤。
      • 範例:
        beq x5, x6, Label
        
        • 如果 x5x6 的值相等,則跳轉到 Label 標籤處繼續執行程式。
    • bne (Branch if Not Equal)
      • 當兩個寄存器的值不相等時,跳轉到標籤。
      • 範例:
        bne x5, x6, Label
        
        • 如果 x5x6 的值不相等,則跳轉到 Label 標籤處。
    • blt (Branch if Less Than)
      • 如果第一個寄存器的值小於第二個寄存器的值(有符號數),則跳轉到標籤。
      • 範例:
        blt x5, x6, Label
        
        • 如果 x5 小於 x6,則跳轉到 Label 標籤。
    • bge (Branch if Greater or Equal)
      • 如果第一個寄存器的值大於或等於第二個寄存器的值(有符號數),則跳轉到標籤。
      • 範例:
        bge x5, x6, Label
        
        • 如果 x5 大於或等於 x6,則跳轉到 Label 標籤。
    • bltu (Branch if Less Than Unsigned)
      • 如果第一個寄存器的值小於第二個寄存器的值(無符號數),則跳轉到標籤。
      • 範例:
        bltu x5, x6, Label
        
        • 如果 x5 小於 x6(作為無符號數比較),則跳轉到 Label 標籤。
    • bgeu (Branch if Greater or Equal Unsigned)
      • 如果第一個寄存器的值大於或等於第二個寄存器的值(無符號數),則跳轉到標籤。
      • 範例:
        bgeu x5, x6, Label
        
        • 如果 x5 大於或等於 x6(作為無符號數比較),則跳轉到 Label 標籤。
    • 沒有bgt(Branch if Greater Than)指令
      • 雖然沒有 bgt 指令,但我們可以使用 blt 來替代,將比較對象對調即可。
      • 範例:
        blt x6, x5, Label
        
        • 這行程式碼的作用相當於 bgt x5, x6, Label

四、Unconditional Jumps

  1. RISC-V 提供兩種類型的跳轉指令:
    • 跳轉到 label
    • 跳轉到儲存在 register 中的 addr.
  2. 使用 jaljalr 指令進行跳轉,並且會更新 PC(Program Counter)來決定下一行指令的位置。
  3. jal 是「Jump and Link」,會把跳轉前的位置儲存在暫存器中,以便跳轉結束後返回。
  4. 例子:jal x1,Labeljalr x1,x5,0

五、C Loop Mapped to RISC-V Assembly

如何將 C 語言中的 for 迴圈轉換成 RISC-V 組合語言:

  • C 語言的程式:
    int A[20];
    int sum = 0;
    for (int i=0; i < 20; i++)
        sum += A[i];
    
  • 對應的 RISC-V 程式碼包含初始化、迴圈條件檢查以及對變量 sum 的累加。

六、為何要使用 Link

  1. 使用 jal 跳轉到指定的標籤,同時將返回位置儲存在 register 中,允許程式可以在跳轉完成後返回。
  2. jal 常用來模擬函數的行為。
  3. 例子展示了如何使用 jal 跳轉到函數,並使用 jr 指令返回。

七、Miscellaneous Instructions(其他指令)

這些指令不屬於其他分類,常作為輔助功能來使用:

  • lui, auipc:這兩個指令通常作為幫助指令來讓偽指令 li(加載立即值)和 la(加載地址)工作,很少單獨使用。

    • 例如:li x5,0xDEADBEEF 將立即值 0xDEADBEEF 儲存到 register x5。
    • 例如:la x5,Label 將標籤 Label 的地址載入到 register x5。
  • ebreak:這是與除錯器相關的行為。在一些模擬器中,這會停止程序執行,讓使用者可以插入來調試,就像其他除錯器中的中斷點一樣。

  • ecall:這是與作業系統相關的行為,涵蓋了程式無法自行完成的任務,例如輸出數據或通過 malloc 請求記憶體。

八、RISC-V Extensions(RISC-V 擴展)

RISC-V 提供了許多可選擇由 CPU 實作的擴展:

  • 乘法/除法擴展:由於乘法和除法運算在基本指令集上運行太慢,因此通常不包括在內,作為擴展來提供。

  • 浮點數擴展:需要更多的硬件電路來支持浮點運算。

  • 雙精度擴展:需要更多的硬件電路,且需要 64 位寄存器來支持雙精度運算。

  • 其他擴展:針對不同的應用場景提供的擴展。

  • 範例指令:

    • mul x5,x6,x7: 將 register x6 和 x7 的值相乘,並將結果存入 x5。

九、Summary

  1. 我們使用的所有結構(變數、函數、迴圈)都需要用這些 RISC-V 指令來構建。
  2. RISC-V 沒有精密的保護措施,容易出錯。為了確保每個人的 code 相容,才需要遵循一套約定。

上一篇
[Day04] RISC-V Instructions (2/3)
下一篇
[Day06] 工具介紹:Ripes
系列文
RISC-V 與處理器之架構學習及應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言