装配,溢出检测

时间:2013-02-14 10:59:00

标签: assembly binary mips

我正在使用pcspim。 我有两个N位长度的二进制数。(2的补码) 说其中一个是8美元(注册8) 另外一个是9美元(注册9) 这个数字是相应给定数字的“2补码”。 (一个2的补码在寄存器8中, 另外2的补码在寄存器9)

我想做以下事情: 添加这两个数字 如果没有溢出正数,则设置所有0的寄存器(比如10美元),如果有溢出,则设置所有寄存器。 设置任何寄存器(比如11美元)给所有0,如果没有溢出,负数加上并设置所有1,如果有溢出。

(在一个案例中,我有2个正数的2个补码(8美元和9美元), 在2-n的情况下,我有2个负数的补码(8美元和9美元))

我该怎么做? (不使用if)

对于这些数字不是两个补码的情况,我只能将相加位数的加法结果移位,以检测溢出。

我不认为在这种情况下该怎么做。

4 个答案:

答案 0 :(得分:3)

正如已经注意到的那样,当符号的符号相同以及它们的和的符号不同时,就会发生符号整数溢出。

示例(为简洁起见,使用8位数字):

0x7F (+127) + 0x00 (+0) = 0x7F (+127)  
0x7F (+127) + 0x01 (+1) = 0x80 (-128) overflow  
0x80 (-128) + 0x7F (+127) = 0xFF (-1)  
0x80 (-128) + 0xFF (-1) = 0x7F (+127) overflow

IOW,

overflow = (sign1 is equal to sign2) AND (sign of sum is NOT equal to sign1)

您可以使用XOR表达相等:

0 XOR 0 = 0 - equal
0 XOR 1 = 1 - not equal
1 XOR 0 = 1 - not equal
1 XOR 1 = 0 - equal

然后:

overflow = (NOT(sign1 XOR sign2)) AND (sign of sum XOR sign1)

你可以用这样编写这个部分:

addu $10,$8,$9 # bit 31 of r10 = sign of sum
xor $10,$10,$8 # bit 31 of r10 = sign of sum XOR sign1
xor $2,$8,$9 # bit 31 of r2 = sign1 XOR sign2
nor $2,$2,$2 # bit 31 of r2 = NOT(sign1 XOR sign2)
and $10,$10,$2 # bit 31 of r10 = (NOT(sign1 XOR sign2)) AND (sign of sum XOR sign1)

现在,如果你想将r10的第31位扩展到寄存器的所有其他位(这样你将在r10中获得全零或全部的0),你可以使用算术右移指令:

sra $10,$10,31

答案 1 :(得分:1)

对于正整数,它应该保持(a+b)>a。 如果不是,一个明显的原因是溢出。 为此,有一个slt指令。对于负数,逻辑自然会被反转。

在c中,工作代码是:

 overflow==((a+b)<a)^(b<0);

并在MIPS汇编程序中:

 add $8, $8, $9
 slt $11, $9, $0    // is 'b' < 0 ?
 slt $10, $8, $9    // is 'a+b' < b ?
 xor $10, $10, $11  // combine the expressions

我不知道,为什么要分别测试负面与正面OF的条件,但那些会是:

 negative_overflow == overflow && (b<0) 
    and $11, $11, $10
 positive_overflow == overflow && (b>=0)
    slt $9, $0, $9     // 0<b
    and $10, $10, $9   // wasting 'b'

答案 2 :(得分:0)

您需要检查结果的符号位。如果你添加2个正数并且最终得到负数,那么在2的补码中你就会溢出。同样,如果你添加2个负数并以正数结束,那么你就会溢出。添加正数和负数不会溢出。

答案 3 :(得分:0)

只有当我们添加两个具有相同符号的数字并在结果中得到不同的符号时才会发生符号溢出(为什么?)。因此:

    subu $t0,$t1,$t2 # subtract and don’t trap
    xor $t3,$t1,$t2 # check to see if the signs of the inputs are different
    bgez $t3,skip # if they aren’t different, no overflow
    xor $t3,$t0,$t1 # check to see if the signs of the difference and first input are different
    blz $t4,overflow # if they’re different, there has been overflow
skip:
    # setup a register you wish with all zeroes
overflow:
    # setup the register with all bits one

如果你想放弃bgez,你必须要有创意;您可以使用$t3中的结果来计算结果,并根据需要使用符号扩展来设置$10