Assembly 在MIPS中使用addi vs addiu的特定情况

Assembly 在MIPS中使用addi vs addiu的特定情况,assembly,mips,integer-overflow,mars-simulator,Assembly,Mips,Integer Overflow,Mars Simulator,我读过几篇关于addiu的帖子,我想如果我知道一些特定情况/案例的例子,当使用addiu优于addi,反之亦然时(以及为什么更好),这将有助于我理解 这篇文章指出处理地址和地址加法使用addiu来防止溢出的“陷阱”很重要。但是,它似乎说陷阱甚至没有真正的好处,那么我为什么要使用addi而不是addiu呢 我的教授似乎只是在努力提醒我们addiu的存在,也许???但它有时会让我困惑不解,“在这种情况下,我真的需要使用addiu吗?还是他们只是为了“好玩”而使用它?” 那么我为什么要使用addi而不

我读过几篇关于addiu的帖子,我想如果我知道一些特定情况/案例的例子,当使用addiu优于addi,反之亦然时(以及为什么更好),这将有助于我理解

这篇文章指出处理地址和地址加法使用addiu来防止溢出的“陷阱”很重要。但是,它似乎说陷阱甚至没有真正的好处,那么我为什么要使用addi而不是addiu呢

我的教授似乎只是在努力提醒我们addiu的存在,也许???但它有时会让我困惑不解,“在这种情况下,我真的需要使用addiu吗?还是他们只是为了“好玩”而使用它?”

那么我为什么要使用addi而不是addiu呢

一般情况下,您不应该这样做,除非作为一种
assert()
在加法中没有2的补码符号溢出。
您可能希望在有符号值的情况下不会溢出,特别是在手工编写asm时。(编译器从不使用
add
,始终使用
addu

除此之外,指令在字面上完全相同,包括
addiu
的16位立即数的符号扩展。(不像
ori
和其他零扩展的布尔运算。MIPS确实要求某些指令的零扩展,但是
addiu
的符号扩展意味着它不需要
subiu
操作码来减去小整数。)

在一个供您自己使用的程序中,让您的程序在错误输入上出错可能比让不应该的东西包装好。如果您是为Linux MIPS而不是MARS编写的,那么您可以为SIGFPE(算术异常)安装一个信号处理程序,这样您至少可以打印一条人性化的错误消息,如“检测到签名溢出,正在中止”。在火星上,我想你会被扔进调试器


唯一存在
add
addi
的原因是整数溢出检测。

整数溢出检测是一个难题。(另见)。ISA已经做出各种尝试,为it提供硬件支持,让软件(特别是高级编译语言)能够正常使用it。MIPS的
add
/
sub
指令就是这样一种尝试,但不包括像左移这样的情况。因此,希望在每个操作上提供溢出检查的高级语言需要一个单独的机制。或者他们可能只使用另一种机制,而根本不使用
add
/
sub

作为MIPS的对比,考虑一个类似于X86或ARM的ISA:它们有一个标志或状态登记器,带有一个已签名的溢出位,以及一个方法,如果最后一个指令集位,则执行一个条件分支。x86甚至还有一条

(如果在标志中设置了OF,则为trap)指令

但是MIPS根本没有标志寄存器,只有整数寄存器。因此,除了通过像
add
这样的add和branch指令之外,没有任何地方可以记录加法溢出的事实。在不花费任何比特来编码溢出情况下的分支目标的情况下,唯一真正的选择是陷阱/异常

(好的,另一个更容易使用的选择是可以设置一个特殊的寄存器,但是上下文开关必须保存/恢复它。它必须像JAL一样工作,以记录哪些添加错误。这可能需要微码,MIPS避免了微码。或者至少要对这种特殊情况进行更复杂的处理,因为它像一个异常,但不是异常,并且在像
beq
这样的情况下无法尽早检测到,因为它确实需要一个完整的32位加法结果。)


为什么MIPS的架构师将普通加法指令命名为
addu
? 我不知道,也许他们是硬件的人,而不是软件的人,他们过于乐观地认为他们将迎来一个新的校验算术时代,并使许多整数溢出错误成为过去

事后来看,给编译器经常使用的标准非补漏白版本赋予
add
助记符最有意义。那么补漏白版本需要另一个名称。可能是
addt
(补漏白)或
addc
(添加选中)但是
addc
很糟糕,因为它与add和其他ISA混淆,通常
adc
add
(添加签名)是可能的。命名很难


基础知识:在一些明显的情况下,您需要使用
addu

对于(可能)大的无符号整数,使用
addu
显然很重要
0x7fffffff+1
对于无符号整数没有什么特别之处。但是它是2的补码有符号溢出,从INT_MAX到INT_MIN,因此
add
会被捕获

对于指针,使用
addu
可能很重要。除非您使用的是“高半内核”内存模型,其中一个数组不可能从
0x8000000
以下开始,然后在其上结束


下面是我回答这个问题的第一个版本。部分内容与上面的内容重复。但我认为不是全部。(TODO:完成编辑;我现在没有时间,但我认为现在发布比以后再发布更有用。)

何时使用addiu优于addi,反之亦然(以及为什么更好)

仅当您特别希望机器在2的补码有符号溢出时使用
add
/
addi
(也称为故障,引发异常)(例如,像INT_MAX+1这样的环绕变为INT_MIN)

大多数时候