我想存盤3*2^16 9在$t0. 我做到了lui $t0,3,我做到了addi $t0,$t0,3。順便說一句,在教科書中,價值是通過創建ori后操作lui。我的做法有問題嗎?兩者有什么區別?
uj5u.com熱心網友回復:
兩者有什么區別?
雙方ori并addi允許16位立竿見影。
但是,ori將零擴展立即數,因此換句話說,立即數始終被視為正數,因此在 32 位中,擴展立即數的高 16 位將為零。
而addi將符號擴展立即數,因此它被視為 16 位有符號值,可以是正數或負數。
兩者都可以,但在使用時addi要注意:如果低16位設定了符號位,那么由于符號擴展和加法的性質,它會產生遞減高位的效果,因此需要添加一到上層立即。例如,假設我們要加載一個常量 0x23458765。本lui應給予0x2346不是0x2345,那么addi得到0×8765,這是否定的,因為一個16位有符號立即,因此會減一經提供的0x23460000 lui,使其0x23458765。
另一個區別是addi會在溢位時陷入困境,這將是一個非常不受歡迎的副作用。 ori不會陷入溢位。但是,我們可以addiu改為使用,因為它也不會在溢位時陷入困境,并且使用與addi.
注意:匯編程式通常會按照您的意圖進行操作,而不是您指定的操作。在某些匯編程式中addi或addiu在某些匯編程式中使用 0x8765將生成多條指令以將該數字容納為正數。例如,如果你想用 MARS 測驗上述序列,我們將不得不使用 -30875 (10)而不是 0x8765 來讓匯編器生成一個立即數 0x8765,否則它將使用多條指令來構建 34661 (10 )。(使用 -30875 withori也會生成多條指令,因此我們必須使用 0x8765 或 34661 在一條指令中獲得立即數。)
我的做法有問題嗎?
總之,您可以使用任何您喜歡的代碼序列來構建您的常量。雖然有些文本只會顯示一種方式,但其他文本肯定是可能的,并且沒有“正確”的方式。
話雖如此,但是,如果您使用匯編器偽函式%hiand %lo,則這些偽函式是為與addiu-一起使用而設計的,這意味著%hi如果低 16 位顯示為負立即數,則將執行 1。這些函式的用法如下:lui $t0, %hi(label); addiu $t0, $t0, %lo(label)— 其中label是(代碼或資料)標簽,但也可以是 32 位常量。(MARS 不支持這些函式,所以用 MARS代替,我們使用li或la偽指令,它會根據需要生成一兩條指令。)
至于原因%hi,并%lo以這種方式作業的,有時序列使用負載(例如lw)或存盤(例如sw)代替addiu,所有的負載和商店也以相同的16位有符號立即數(作業,所以也會有當低 16 位變為負數時遞減高位部分的潛在影響)。(這些序列 ( lui; lw/ sw) 可以在這里和那里保存指令,例如,如果意圖是訪問全域變數。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/347747.html
