我正在設計自己的 RISC-V CPU,并且已經能夠實作一些指令代碼。
我已經安裝了 RV32I 版本的 GCC 編譯器,所以現在可以使用匯編器了riscv32-unknown-elf-as。
我試圖用一條指令組裝一個程式:
# simple.asm
add x5,x6,x7
我用匯編器編譯它,然后用這個命令運行 objdump:
riscv32-unknown-elf-as simple.asm -o simple
riscv32-unknown-elf-objdump -D simple
這將列印出以下內容:
new: file format elf32-littleriscv
Disassembly of section .text:
00000000 <.text>:
0: 007302b3 add t0,t1,t2
Disassembly of section .riscv.attributes:
00000000 <.riscv.attributes>:
0: 2d41 jal 0x690
2: 0000 unimp
4: 7200 flw fs0,32(a2)
6: 7369 lui t1,0xffffa
8: 01007663 bgeu zero,a6,0x14
c: 00000023 sb zero,0(zero) # 0x0
10: 7205 lui tp,0xfffe1
12: 3376 fld ft6,376(sp)
14: 6932 flw fs2,12(sp)
16: 7032 flw ft0,44(sp)
18: 5f30 lw a2,120(a4)
1a: 326d jal 0xfffff9c4
1c: 3070 fld fa2,224(s0)
1e: 615f 7032 5f30 0x5f307032615f
24: 3266 fld ft4,120(sp)
26: 3070 fld fa2,224(s0)
28: 645f 7032 0030 0x307032645f
我的問題是:
- 這里發生了什么?我以為我會有一個簡單的單行十六進制,但還有很多事情要做。
- 如何指示我的處理器開始讀取某個記憶體地址處的指令?看起來 objdump 也不知道指令將從哪里開始。
Just to be clear, I'm treating my processor as bare metal at this point. I am imagining I will hardcode in the processor that the instructions start at memory address X and data is available at memory address Y and stack is available at memory address Z. Is this correct? Or is this the wrong approach?
uj5u.com熱心網友回復:
處理器如何知道從哪個地址開始獲取指令?
實際的 CPU 本身會有一些硬連線地址,它可以在復位/上電時從中獲取。通常,系統會在該物理地址處設計有 ROM 或閃存。(并且可能有一個 ELF 程式加載器的代碼,它將尊重 ELF 入口點元資料,或者您可以在二進制檔案的開頭將一個平面二進制檔案與正確的代碼鏈接起來。)
這里發生了什么?我以為我會有一個簡單的單行十六進制,但還有很多事情要做。
您objdump -D反匯編了所有 ELF 部分,而不僅僅是 .text。如您所見,.text 部分中只有一條指令,如果您使用了 objdump -d,您會看到這樣的內容。(我通常使用objdump -drwC,盡管-w沒有換行可能與 RISC-V 無關,這與 x86 不同,其中單個 insn 可能很長。)
是否可以將我上面編譯的檔案按原樣傳遞給我的處理器?
不是你想的那樣。另請注意,您為輸出選擇了錯誤的檔案名。as 生成目標檔案(通常為 .o),而不是可執行檔案。您可以鏈接ld到一個平面二進制檔案,或者鏈接和objcopy其中的.text部分。
(理論上,您可以將整個 ELF 可執行檔案甚至目標檔案放入 ROM 中,以便該.text部分恰好從 CPU 獲取的位置開始,但不會查看元資料位元組。因此,ELF 中的 ELF 入口點地址元資料可執行檔案無關緊要。)
a.o和可執行檔案之間的區別:a.o只具有重定位元資料供聯結器填充實際地址,絕對用于la偽指令,或相對用于auipc多個.o檔案,其中一個參考另一個符號。(否則可以在組裝時計算相對位移,而不是在鏈接時計算。)
因此,如果您的代碼使用任何記憶體地址標簽,則需要聯結器在代碼中填寫這些重定位條目。然后你可以objcopy從鏈接的 ELF 可執行檔案中提取一些部分。或者使用聯結器腳本來設定平面二進制檔案的布局。
對于只有 an add、 nola或任何內容的簡單情況,沒有重定位條目,因此 中的文本部分.o與鏈接的可執行檔案中的相同。
同樣棘手的objcopy是靜態資料,例如.data和.bss部分。如果您只將該.text部分復制到平面二進制檔案,則在任何地方都不會有資料。(但在 ROM 中,您需要一個啟動函式,將 ROM 中的靜態初始值設定項復制到 RAM 中.data,并將.bss空間歸零。如果您想將 asm 源撰寫為具有.data非零值的正常外觀部分,您'd 希望您的構建腳本確定要復制的大小,以便您的啟動功能可以使用它,而不必手動執行所有操作。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/347742.html
標籤:assembly cpu-architecture elf riscv riscv32
上一篇:哪些架構具有模/非模移位?
