2017-09-30 89 views
1

如果你給出:轉換C++函數MIPS

calc (int b) { 
return b - 2; 
} 

會是怎樣轉化爲MIPS?

我已經考慮了以下幾點:

addi $v0, $a0, -2 
jr $ra 
*********************** 
jr $ra 
addi $v0, $a0, -2 
*********************** 
addi $v0, $a0, 2 
jr $ra 
*********************** 
lw $v0, 0($a0) 
addi $v0, $v0, -2 
jr $ra 

我只是學習功能MIPS和將不勝感激的意見。在這種情況下使用'lw'指令有什麼意義嗎?

+4

Andre,你的ABI變量中的參數是如何傳遞的,返回地址存儲在哪裏? MIPS的版本是什麼?它是否有「分支[延遲插槽](https://en.wikipedia.org/wiki/Delay_slot)」? LW用於從RAM內存中加載數據:https://en.wikipedia.org/wiki/MIPS_architecture#Loads_and_stores – osgx

回答

1

您的結果是正確的,至少是第一個。根據here您的第一個回答:

addi $v0, $a0, -2 
jr $ra 

是正確的。它使用最少量的指令來提高執行速度,更不用說使用即時指令減少內存中的提取。看看鏈接中的表格,並會告訴你:

  • $v0是函數的第一個返回值應該去的寄存器。
  • $a0是調用函數時使用的第一個輸入參數的寄存器。
  • $ra是寄存器保存來自先前跳轉指令的返回地址。

所以有人想打電話給你的彙編函數它會是什麼樣子:

int x = calc(5); // This line is the `C` equivalent and not part of assembly code. 

大會將是:

li $a0, 5 # Load immediate the value 5 into register $a0. 
jal __calC# Jump to the sub routine '__calc' and store return address in $ra. 
      # Result will now be in $v0. 
... 

__calc: 
    addi $v0, $a0, -2 
    jr $ra 

嘗試從像lw說明,如果你能躲得遠遠的。與保存CPU寄存器中的值相比,它們會跳出內存並獲取超慢的內存。

+0

我注意到我在MIPS中編寫的一些函數,包括這一個,當我使用像'lw'或'sw'這樣的指令,我收到一個錯誤。 通常,錯誤消息顯示爲:「提取地址未在字邊界上對齊」。這是否意味着你提到從RAM中獲取值?請記住,我正在使用: ori $ a0,$ 0,5 將$ a0初始化爲5用於測試目的。如果我不限制$ a0的價值,你認爲我可以使用'lw'指令來避免錯誤嗎?這只是出於好奇,我已經對你的答案感到滿意。 – Andre

+1

如果你想在寄存器'$ a0'中的'5'這樣的寄存器中得到一個值,你可以使用'load immediate'指令'li'。 'li $ a0,5'與$ a0 = 5相同。當使用像'lw'和'sw'這樣的指令時需要寄存器和RAM地址。如果你使用'lw $ a0,5',就像將地址'5'處的RAM的內容加載到'$ a0'中一樣,RAM中的內容可以是任何東西。 RAM地址'5'可能會限制內核使用,用戶空間內存在RAM地址中開始較高,這會導致提取錯誤。 – user2205930

+1

'提取地址不符合WORD邊界'的問題是另一個問題。WORD是CPU的寄存器大小,假設你的情況爲32位。這意味着在讀寫RAM時,您提供的地址必須是32位對齊的。不知道你的設置的確切細節,這是我能給出的最佳答案。通常任何RAM地址都是有效的。 – user2205930