2017-04-21 105 views
0

我正在編譯(使用RV32I彙編程序)以下代碼 - 沒有在命令行上發佈錯誤。RiscV彙編程序 - 輸出不是我期望的寄存器和立即操作數

slt   x15,x16,x17  # line a 
    slt   x15,x16,22  # line b immediate operand 
    slti  x15,x16,22  # line c 
    sltu  x15,x16,x17  # line d 
    sltu  x15,x16,22  # line e immediate operand 
    sltiu  x15,x16,22  # line f 

我注意到,爲b行生成的機器碼與爲c行生成的機器碼相同。我注意到與e和f行相同的情況 - 來自這兩行的機器代碼是相同的。這臺機器輸出的這些具體說明,並不符合我的期望。彙編器不應該拋出一個錯誤或警告,說明這些操作數在技術上對於「slt x15,x16,22」不正確 - 並且應該使用該指令的立即版本 - 「slti x15,x16,22」?我用'-warn'選項調用匯編程序。

這個結果似乎無法達到這些指令的兩個不同版本的目的。一個版本,其中所有操作數都是寄存器,另一個版本具有寄存器和一個立即操作數。如果打算使用'x22'而不是'22'呢?

+0

什麼是確切的彙編程序命令行(我們需要彙編程序名稱和版本以及所有使用的選項)?什麼是'objdump -d',啓用了十六進制轉儲?彙編程序不僅可以接受來自spec的真實指令,還可以接受一些綜合助記符和操作名稱,將其轉換爲可接受參數的真實操作碼。 – osgx

+0

osgx-我刪除了我的評論。我認爲他們太難以閱讀和混淆 - 在我重讀他們之後,我不太確定他們是否一致。代碼和命令確實需要格式化,我似乎無法在此「添加評論」實用程序中執行此操作。 – daveW

+0

osgx(續) - 這是一個難以提供詳細代碼和命令流的論壇。當我在接下來的幾天裏得到時間時 - 我會建立一些詳細的測試用例,我傾向於在GitHub上發佈這個問題,我認爲可讀性得到了很大的提高。另外 - 我想回去比較RV64和RV32彙編器輸出。但是,我承認你的觀點 - 在這裏需要更多的細節來取得進展。無論如何,這些特定命令在這裏肯定有些不可思議。 – daveW

回答

0

正如在評論中提到的,我已將此問題移至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輸入操作數來自寄存器文件輸出或從指令字中剝離的立即數。

所以,我原來的問題的答案 - 「爲什麼這會創建完全相同的機器碼?」 - 「是因爲這是彙編程序的工作原理」。但是就目前而言 - 這個功能在大多數情況下都能正常工作。

+0

用於SLT/SLTI反彙編的列表文件輸出的問題被確認爲錯誤。當我創建一個測試用例來顯示列表文件的「objcopy」操作中的問題時,進度迅速移動。代碼已被更改併合並。您可以在riscv-next分支上的GitHub riscv/riscv-binutils-gdb中查看詳細信息。參見問題「修復SLTI反彙編#80」。一旦我發佈了測試用例 - 安德魯和帕爾默就非常迅速地跳出了這個問題。我沒有構建和測試riscv/riscv-binutils-gdb riscv-next分支,所以我無法測試操作。 – daveW

+0

另一方面 - 似乎不需要明確的SUBI指令,因爲ADDI始終是符號擴展的。 – Onofog