簡體   English   中英

MIPS中lui之后的ori操作和add操作有什么區別?

[英]What is the difference between an ori operation and an add operation after lui in MIPS?

我想在$t0存儲3*2^16 + 9 我做了lui $t0,3 ,我做addi $t0,$t0,3 順便說一下,在教科書中,值是通過lui之后的ori操作創建的。 我的做法有問題嗎? 兩者有什么區別?

兩者有什么區別?

oriaddi允許 16 位立即數。

但是, ori將零擴展立即數,因此換句話說,立即數始終被視為正數,因此在 32 位中,擴展立即數的高 16 位將為零。

addi將對立即數進行符號擴展,因此它被視為 16 位有符號值,可以是正值也可以是負值。

兩者都可以,但是在使用addi我們必須小心如下:如果低 16 位設置了符號位,那么根據符號擴展和加法的性質,它將產生遞減高位部分的效果,因此需要在上面的立即數上加一個。 例如,假設我們要加載一個常量 0x23458765。 lui應給予0x2346不是0x2345,那么addi得到0×8765,這是否定的,因為直接簽訂16位,因此會減一經提供的0x23460000 lui ,使其0x23458765。

另一個區別是addi會在溢出時陷入困境,這將是一個非常不受歡迎的副作用。 ori不會陷入溢出。 但是,我們可以使用addiu代替,因為這也將溢出不是陷阱,並使用相同的16位有符號立即為addi

注意:匯編程序通常會按照您的意圖進行操作,而不是您指定的操作。 使用0×8765與addiaddiu在某些匯編器將生成的多個指令,以適應該數目為陽性。 例如,如果你想用 MARS 測試上述序列,我們將不得不使用 -30875 (10)而不是 0x8765 來讓匯編器生成一個立即數 0x8765,否則它將使用多條指令來構建 +34661 (10 ) (使用 -30875 和ori也會生成多條指令,因此我們必須使用 0x8765 在一條指令中獲得立即數。)

我的做法有問題嗎?

總之,您可以使用任何您喜歡的代碼序列來構建您的常量。 雖然有些文本只會顯示一種方式,但其他文本肯定是可能的,並且沒有“正確”的方式。

話雖如此,但是,如果您使用匯編器偽函數%hi%lo ,它們是為與addiu一起使用而addiu ——這意味着如果低 16 位將顯示為負立即數,則%hi將執行 +1。 這些函數的用法如下: lui $t0, %hi(label); addiu $t0, $t0, %lo(label) lui $t0, %hi(label); addiu $t0, $t0, %lo(label) — 其中label是(代碼或數據)標簽,但也可以是 32 位常量。 (MARS 不支持這些函數,所以在 MARS 中我們使用lila偽指令代替,它會根據需要生成一兩條指令。)

%hi%lo以這種方式工作的原因是有時序列使用加載(例如lw )或存儲(例如sw )而不是addiu ,並且加載和存儲也使用相同的 16 位有符號立即數. (這些序列可以在這里和那里保存一條指令,例如,如果意圖是訪問全局變量。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM