所以我正在寫一個有很多常量整數值的彙編程序。在MIPS中聲明整數值
我知道在.data部分中,我可以爲數據類型指定一個帶有.word數據類型的標籤,並鍵入我的數字。有了這個方法,我仍然需要在main中加載一個地址。
但在主,我可能只是簡單地使用
李$ T1,some_number
是這些方法的任何一個比另一個,爲什麼好?
所以我正在寫一個有很多常量整數值的彙編程序。在MIPS中聲明整數值
我知道在.data部分中,我可以爲數據類型指定一個帶有.word數據類型的標籤,並鍵入我的數字。有了這個方法,我仍然需要在main中加載一個地址。
但在主,我可能只是簡單地使用
李$ T1,some_number
是這些方法的任何一個比另一個,爲什麼好?
通常我會說使用li
是更好的方法。您可以避免在.data
部分添加一堆混亂,並且在某些情況下您還可以獲得更高效的代碼。
讓我們來看一些例子:
.data
ten: .word 10
million: .word 1000000
.text
main:
lw $t0,ten
li $t1,10
lw $t2,million
li $t3,1000000
瞭解這裏既lw
和li
是是會轉換成一個或多個實際指令僞指令這一點很重要。 lw
確實存在於MIPS指令集中,但是它的這個特殊變體卻沒有。 MIPS指令集中不存在li
。
如果我們看一下SPIM前兩個指令產生,我們可以看到:
[0x00400024] 0x3c011001 lui $1, 4097 ; 9: lw $t0,ten
[0x00400028] 0x8c280000 lw $8, 0($1)
[0x0040002c] 0x3409000a ori $9, $0, 10 ; 10: li $t1,10
所以這是對lw
變種一個額外的指令,作爲地址首先必須加載到寄存器,那麼該值將從該地址加載。這也意味着一個額外的(可能較慢的)內存訪問(當然,如果您計算指令提取次數,則是兩個)。
現在讓我們來看看其他兩個指令,要加載的值過大,單一的指令進行編碼:
[0x00400030] 0x3c011001 lui $1, 4097 ; 11: lw $t2,million
[0x00400034] 0x8c2a0004 lw $10, 4($1)
[0x00400038] 0x3c01000f lui $1, 15 ; 12: li $t3,1000000
[0x0040003c] 0x342b4240 ori $11, $1, 16960
這裏立即1000,000使用兩個指令作爲(15 << 16) | 16960
加載。因此這兩個變體都需要兩條指令,但li
變體不需要從內存中讀取。
如果你想一個有意義的名字分配給一個常數,以避免在你的代碼,你可以用=
這樣做的幻數:
TEN = 10
li $t0, TEN # Expands to li $t0, 10
也許你可以避開通過使用$gp
-relative尋址一直加載地址爲lw
,但我覺得這超出了這個問題的範圍。
感謝您的廣泛答覆! – ASchmalzWorld