繁体   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