如何检查两个签名的32位整数是否会导致MIPS溢出?
问题描述:
我已经想通了,两个无符号整数,我可以做到这一点:如何检查两个签名的32位整数是否会导致MIPS溢出?
sll $a0, $a0, 31 #a0 is integer 1 to be added
sll $a1, $a1, 31 #a1 is integer 2
add $t0, $a0, $a1 #result in $t0
addi $t1, $0, 2
beq $v0, $t0, $t1
这样做是它变为两个整数到第一位点的第32位,并将其添加他们。如果这两个数字都是1,那么$ t1中的答案将是2(01 + 01 = 10)。因此,发生了溢出。
但是对于有符号整数,前导符表示负整数。我排除了溢出的可能性,两个整数都是符号相反,但假设它们是相同的符号。然后010 + 011(两个正整数)会给我101,但是因为这是签名的。这成为一个负整数。我只是检查一下数字是否有变化的迹象?对于两个负整数,我可以检查它是否未签名?
答
所以你说的是签名溢出?如果进位与执行不匹配,那么它是一个有符号溢出。
abi or
000 00
001 01 signed overflow
010 01
011 10
100 01
101 10
110 10 signed overflow
111 11
a和b是操作数,i是进位,o是执行,r是结果。
注意到a,b和r之间的关系?您只需查看两个操作数的msbits和结果即可确定符号溢出。
这与mips绝对无关,它是基本二进制补码(和减法)。要将其应用于指令集,您需要隔离操作数的msbits,并且它们与结果匹配。可以使用测试/并且可以使用,假设它用已知的东西填充(比如零并且不符号扩展,或者可能的符号扩展帮助),则移位31位。用零添加检查z标志。 mips并不使用标志,所以或者转向隔离,然后比较,如果相等或不是一个好的通用解决方案。可以同时进行测试和执行(并且两个操作数都是0x7FFFFFFF然后加上,然后右移31,或者隔离进位和两个操作数msbits,然后添加这三个项目并查看执行结果是否相同或者不同,需要更多的指示)。
即使您的未签名也不能正常工作。你的'beq'是无效的语法,并且使用'$ v0'而不被引用。你想_right_移位,所以你想'srl'而不是'sll'。测试失败。如果两个数都是-1(即'0xFFFFFFFF'),那么当你添加它们时就得到-2(即'0xFFFFFFFE')。这不会导致溢出。但是,我相信你的测试会认为它会。 –