2015-09-06 68 views
0

所以我正在寫一個有很多常量整數值的彙編程序。在MIPS中聲明整數值

我知道在.data部分中,我可以爲數據類型指定一個帶有.word數據類型的標籤,並鍵入我的數字。有了這個方法,我仍然需要在main中加載一個地址。

但在主,我可能只是簡單地使用

李$ T1,some_number

是這些方法的任何一個比另一個,爲什麼好?

回答

0

通常我會說使用li是更好的方法。您可以避免在.data部分添加一堆混亂,並且在某些情況下您還可以獲得更高效的代碼。

讓我們來看一些例子:

.data 
ten: .word 10 
million: .word 1000000 

.text 
main: 
    lw $t0,ten 
    li $t1,10 
    lw $t2,million 
    li $t3,1000000 

瞭解這裏既lwli是會轉換成一個或多個實際指令僞指令這一點很重要。 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,但我覺得這超出了這個問題的範圍。

+0

感謝您的廣泛答覆! – ASchmalzWorld