iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Software Development

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

[Day29] 總結與流程 (5/5)

  • 分享至 

  • xImage
  •  

1. 從 C 程式到組合語言(hello.c → hello.s)

  • C 程式 (hello.c):主要包含一個 main() 函數,呼叫 printf 來輸出文字 "Hello, World"。
  • 組合語言檔 (hello.s)
    • 使用 .text 指令來進入文本段,並使用 .align 指令來對齊程式碼。
    • main: 標籤定義了 main 函數的起始位置,組合語言中使用偽指令(pseudoinstruction)來進行堆疊管理、暫存器存取、函數呼叫(例如 printf)。
    • 讀取靜態字串(str1, str2)進行輸出,並進行相應的堆疊回收與返回處理。

2. 從組合語言到目標檔案(hello.s → hello.o)

  • 文本段:將組合語言指令編譯成機器碼。示例中,addi, sw, lui, auipc 這些指令都轉換成了具體的機器碼。
  • 符號表:這是程式中的標籤對應的位址表,如 main 是全局的文本段,str1str2 分別是本地的資料段。
  • 重定位表:某些符號(如 str1, str2)需要在連結過程中確定它們的絕對位址,這些符號會被列入重定位表中,待連結器來處理。

3. 從目標檔案到可執行檔案(hello.o → a.out)

  • 連結過程:在連結階段,Linker 計算出具體的立即數,將符號 str1, str2 的位址轉換為機器碼中可用的位址。
  • 例如,luiaddi 指令的位址計算過程使用了 20 位和 12 位的立即數進行分割和處理。

4. lui/addi 位址計算的詳細說明

  • addi 指令進行符號擴展,來生成 32 位的立即數。例如 str1 的位址 0x20A10,其 12 位立即數部分帶有負號位。
  • Linker 結合 luiaddi 指令,將位址分成上 20 位和下 12 位來處理,最後正確計算出 str1 的位址。

5. 總結與流程圖

  • 編譯器(Compiler):將高階語言(如 C 語言)轉換為組合語言。
  • 組譯器(Assembler):將組合語言中偽指令轉換為機器碼,並生成用於連結的重定位表。
  • 連結器(Linker):將多個目標檔案合併,解決所有符號的絕對位址,並生成最終的可執行檔案。
  • 載入器(Loader):將可執行檔載入記憶體並開始執行程式。

上一篇
[Day28] CALL: Loader (4/5)
下一篇
[Day30] 從抽象層次到效能改善
系列文
RISC-V 與處理器之架構學習及應用30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言