2013-02-14 50 views
1

我正在使用pcspim。 我有两个N位长度的二进制数(2的补码) 说他们中的一个在$ 8(寄存器8) 另一个在$ 9(寄存器9) 这个数字是相应给定数字的“2的补码” 。 (一个2的补数是寄存器8, 另2的补数是寄存器9)装配,溢出检测

我要做到以下几点: 设置任何寄存器(比如$ 10)加这2个数字都为0,如果没有溢出与正数加入并设置所有1如果有溢出。 设置任何寄存器(比如说$ 11)为全0,如果没有溢出负数加入并设置所有1溢出。

(在一种情况下,我有2个在2-N的情况下2张正数(在$ 8和$ 9), 的补我有2个公司的2负号($ 8和$ 9)补)

哪有我这样做? (不使用if)

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

我不知道该怎么办。

回答

0

您将需要检查结果的符号位。在补码的补充中,如果您添加2个正数,并以负数结束,则已溢出。同样,如果您添加2个负数,并以您溢出的正数结束。添加正数和负数不能溢出。

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

+0

谢谢,但我可以执行它,而无需使用标签(如BLZ $ T4,溢出),只是用简单的逻辑运算??? – XXXXX 2013-02-14 11:25:45

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 

我不知道,为什么一个要测试的消极与积极的单独的条件,但那些将是:

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

如前所述,有符号整数溢出发生时,加数是相同的,当它们的和的符号不同时。

例子(与简洁的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 

督察,

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) 

你可以这部分代码是这样的:如果你想R10的31位扩展到寄存器的所有其他位(这样你会得到全零或全一,

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),你可以使用算术右移指令:

sra $10,$10,31