1

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

我想做以下事情:如果没有溢出,则将这两个数字添加到所有寄存器(例如 $10),如果有溢出,则添加所有正数。如果没有溢出,则将任何寄存器(例如 $11)设置为全 0,负数相加,如果溢出,则设置所有寄存器。

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

我怎样才能做到这一点?(不使用 if)

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

我不知道在这种情况下该怎么办。

4

4 回答 4

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

爱荷华州,

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 中获得全零或全一),您可以使用算术右移指令:

sra $10,$10,31
于 2013-02-14T20:16:29.547 回答
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'
于 2013-02-14T11:25:33.533 回答
0

您将需要检查结果的符号位。在二进制补码加法中,如果您添加 2 个正数并最终得到一个负数,则您已经溢出。同样,如果您添加 2 个负数并最终得到一个正数,则您已经溢出。正负数相加不能溢出。

于 2013-02-14T11:14:06.093 回答
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

于 2013-02-14T11:14:30.587 回答