正如在評論中提到的,我已將此問題移至GitHub上,作爲riscv/riscv-binutils-gdb上的問題#79。
簡短的回答我原來的問題是彙編有一個特點,將轉換像SLTU,至REGx,regY,IMM的指令立即版本的指令 - SLTIU至REGx,regY,IMM。我還沒有看到任何解釋此功能的文檔。
通過試驗,下面是我發現的執行此操作的指令列表。
.text
slt x0,x0,-1 # bug
sltu x0,x0,0 # -> sltiu
add x0,x0,5 # -> addi
xor x0,x0,8 # -> xori
or x0,x0,12 # -> ori
and x0,x0,16 # -> andi
sll x0,x0,6 # -> slli
srl x0,x0,4 # -> srli
sra x0,x0,9 # -> srai
這些說明彙編沒有錯誤或警告。我使用下面的列表文件輸出來驗證機器代碼。 (通過使用x0寄存器簡化了這項任務)。
Disassembly of section .text:
0000000000000000 <.text>:
0: fff02013 slt x0,x0,-1
4: 00003013 sltiu x0,x0,0
8: 00500013 addi x0,x0,5
c: 00804013 xori x0,x0,8
10: 00c06013 ori x0,x0,12
14: 01007013 andi x0,x0,16
18: 00601013 slli x0,x0,0x6
1c: 00405013 srli x0,x0,0x4
20: 40905013 srai x0,x0,0x9
SLT指令將爲SLTI編寫機器代碼,但列表文件顯示SLT - 我認爲這是一個錯誤。有關詳細參數,請參閱GitHub#79。所有其他說明按預期工作。
只有在基本指令中有基本指令對時,此方法纔有效。像ADD/ADDI或XOR/XOI一樣。但是,唉,SUB在RiscV ISA中沒有SUBI指令。我確認了這一點,當我收到一個錯誤,試圖用立即操作數組裝SUB。所以,如果你是懶惰的彙編程序員,並且你不想爲基礎指令使用正確的操作數 - 現在你必須記住除了SUB以外,應該可以正常工作。或者將SUBI指令添加到您的定製RiscV ISA。
以下是一些哲學評論(如果您的RiscV項目明天到期,您可以跳過本答覆的其餘部分)。首先,我對任何開源項目感到內疚。我是一個很長時間的Linux用戶,並且使用了許多開源工具。不僅適用於業餘愛好,還適用於IBM,惠普和戴爾使用的產品。我可能有6個我曾經使用過的裝配工 - 擁有各種專業知識。從8080/8085開始,我已經在大學階段教過彙編語言/計算機體系結構。我不得不承認,圍繞着RiscV有很多專業知識 - 但無論如何,我不認爲自己是裝配工的完全noob。
1)彙編程序應該儘量接近基本指令 - 因此它們在出現偏差時應該有很好的理由。類似這樣的特性,ADD在彙編器內部被轉換爲ADDI - 我覺得這個特性提供的價值很小。國際海事組織從C/C++使用反彙編可能會有一些價值 - 但我不能把它放在手指上。如果有人有關於採取這種方法的一些細節,請發佈。
2) RiscV被吹捧爲新的全新開放式ISA。但是,它與MIPS類似,問題在於MIPS binutils的行李帶有RiscV。好像我已經在「在MIPS中工作,因此它必須在RiscV中工作」,並且正在考慮GitHub#79。
3)如果你不喜歡程序集助記符 - 或者懶得使用正確的操作數指令 - 那麼請考慮編寫一個宏。例如,您可以爲SUB操作編寫一個宏來處理立即參數。抵制將宏觀想法帶入彙編程序的衝動 - 特別是如果它不會被新用戶記錄下來。我發現這個特性與彙編器中的內置宏非常相似。
4)列表文件中的錯誤很重要 - 對某些人來說,它們對驗證任務至關重要。他們應該認真對待並修復。我不確定如果列表文件的SLT到SLTI的錯誤是彙編程序的錯誤,它可能是binutils objdump實用程序中的問題。
5)在ISA中定義的僞指令 - 就像內置的宏一樣。我認爲他們應該謹慎使用。因爲,我認爲他們可以增加更多的困惑。我爲我的堆棧操作(如PUSH和POP)編寫宏。我不介意寫這些宏 - 我不覺得在彙編器或ISA中需要很多僞指令。熟悉gcc/gnu樣式彙編語法的人應該能夠僅使用基本指令快速編寫一些測試代碼,而不必擔心在彙編程序中發現技巧。我偶然發現了SLT技巧(錯字)。
6)在RiscV彙編器中轉換指令的這種技巧是以犧牲「強類型化」操作數爲代價的。如果你犯了一個錯字(就像我做過的那樣) - 但你打算使用基本指令的所有寄存器操作數 - 你將得到立即的指令形式,並且不會發布任何警告。所以認爲這是一個友好的單挑。我更願意在彙編程序中調用KIS原則,並傾向於嚴格執行正確的操作數。或者爲什麼不提供彙編選項來打開/關閉此功能?
7)越來越多的似乎彙編程序主要用於調試和驗證,而不是用於通用軟件開發。如果你需要更多抽象的代碼工具 - 你通常轉向C或C++來獲取嵌入式核心。是的,你可能會瘋狂地編寫許多彙編宏,但在C/C++中編寫代碼要容易得多。您可能使用一些內聯彙編器來優化一些時間關鍵的代碼 - 當然,它有助於反彙編以查看已編譯的C/C++代碼。但是C/C++編譯器已經改進得非常多,以至於很多項目都可能使得程序集優化過時。組件用於啓動代碼 - 例如如果你將Uboot引導程序移植到另一個處理器上,你可能不得不在彙編程序中處理一些啓動文件。所以,我認爲彙編程序的目的已經隨着時間的推移而變化,以適應一些啓動文件的任務,但在調試和驗證方面最具價值。這就是爲什麼我認爲列表文件必須是正確的。具有此功能的命令列表(例如,基於操作數類型從ADD轉換爲ADDI)意味着彙編程序員只需要掌握一條指令。但RiscV無論如何都有一小部分基本指令。如果您對舊的CISC處理器有任何經驗,這一點很明顯。事實上,Risc處理器默認應該有一個小指令集。所以我的問題在我原來的帖子裏 - 爲什麼要有指令的最新版本?答案是 - 對於我已經確定的指示 - 你不需要它們。您可以使用所有寄存器或寄存器對它們進行編碼,並且可以立即生成值 - 彙編程序將計算出結果。但硬件實現絕對需要兩種版本(只註冊操作數和寄存器以及立即操作數)。例如。內核需要引導ALU輸入操作數來自寄存器文件輸出或從指令字中剝離的立即數。
所以,我原來的問題的答案 - 「爲什麼這會創建完全相同的機器碼?」 - 「是因爲這是彙編程序的工作原理」。但是就目前而言 - 這個功能在大多數情況下都能正常工作。
什麼是確切的彙編程序命令行(我們需要彙編程序名稱和版本以及所有使用的選項)?什麼是'objdump -d',啓用了十六進制轉儲?彙編程序不僅可以接受來自spec的真實指令,還可以接受一些綜合助記符和操作名稱,將其轉換爲可接受參數的真實操作碼。 – osgx
osgx-我刪除了我的評論。我認爲他們太難以閱讀和混淆 - 在我重讀他們之後,我不太確定他們是否一致。代碼和命令確實需要格式化,我似乎無法在此「添加評論」實用程序中執行此操作。 – daveW
osgx(續) - 這是一個難以提供詳細代碼和命令流的論壇。當我在接下來的幾天裏得到時間時 - 我會建立一些詳細的測試用例,我傾向於在GitHub上發佈這個問題,我認爲可讀性得到了很大的提高。另外 - 我想回去比較RV64和RV32彙編器輸出。但是,我承認你的觀點 - 在這裏需要更多的細節來取得進展。無論如何,這些特定命令在這裏肯定有些不可思議。 – daveW