首页>Program>source

我对add和addu之间的区别感到困惑。

MIPS指令参考指出:

  • add (with overflow)
  • add unsigned (no overflow)

我的理解是使用带符号操作数的add和带无符号操作数的addu。

但是让我们考虑这个示例(只有6位):

 溢出
 |
 V
 1 | 1 1 1<-携带
  | 1 1 1 1 0 1 +
  | 1 1 1 1 1 0 =
 -----------------
  | 1 1 1 0 1 1

这是我的理由:

  • if I consider the first and second operand signed 数字(二进制​​补码),那么结果是正确的(-3 + -2 = -5),并且我不想溢出异常.因此,我将使用addu来避免这种异常,但是,尽管结果相同,但名称建议使用addu用于无符号数字!
  • 如果我考虑第一个和第二个操作数 unsigned 数字,那么我想引发一个异常(因为61 + 62不等于59).因此,我将使用add引发异常,而不是使用addu来引发异常。

现在我的问题是:

  • assuming that operands are signed (negative in the example above) numbers, should I use addu (as my reasoning suggests) or I should use add (as the name suggests)?
  • assuming that operands are unsigned (positive) numbers, should I use add (as my reasoning suggests) or addu (as the name suggests)?
最新回答
  • 11天前
    1 #

    指令名称具有误导性.使用 addu 对于有符号和无符号操作数,如果您做 not 想要一个溢出陷阱.

    使用 add 如果由于某种原因需要溢出陷阱.大多数语言都不想在有符号的溢出上设陷阱,所以 add 很少有用。

  • 11天前
    2 #

    如果您使用带符号的数字,则应使用 add 如果您希望在结果溢出时生成陷阱。

    如果使用无符号数字,则应始终使用 addu 并通过将结果与两个数字进行比较来检查加法运算是否溢出(如果结果小于操作数,则加法运算会溢出)。

    这里有一个片段,展示了如何检查未签名加法中的溢出:

       li $a1, 0xFFFF0FFF
        li $a2, 0x00010000
        addu $a3, $a1, $a2  # This unsigned addition overflows (set $a3 to $a1+$a2)
        bgt $a1, $a3, overflowed
        bgt $a1, $a2, overflowed
        # If you get here, unsigned addition did not overflow
      # your code goes here...
    overflowed:
        # If you get here, unsigned addition overflowed
      # your code goes here...
    

  • 11天前
    3 #

    OVERFLOw是 NOT 如问题中所声明的,该进位位不是溢出位,在给定的示例中没有溢出,溢出发生在以下情况:

    MSB1 = 1 && MSB2 = 1 && MSBofRESULT = 0
    OR
    MSB1 = 0 && MSB2 = 0 && MSBofRESULT = 1
    

    所以要坚持 它会标记为溢出,并且示例中的进位位(不是溢出)不会打扰您. add 除了没有异常外,其他功能都相同。

  • 11天前
    4 #

    addu 因此,在MIPS中,它们使用31位存储数据,最大数量为(2提高到31)-1,并保留1位用于存储数字符号.如上所述," add"和" addu"之间的基本区别在于,当结果数大于最大位数(而不是占用31位)时,前者会引发异常.后者执行时不会显示任何警告。

    例如,3位加法最大数=(2 **(n-1))-1分钟数=-(2 **(n-1)) 所以在我们的例子中,max = 3,min = -4

    Basically both opcodes are signed addition.
    

    就是这样。

  • 11天前
    5 #

    实际上在您的示例中并不是溢出.当符号位的进位不等于符号位的进位时,会发生溢出.在您的示例中,尽管符号位的进位为" 1"(看似溢出),但进位符号位也为" 1".因此,在这种情况下,MIPS不会将其视为溢出.溢出如何发生的模式实际上与结果是否正确相对应.也就是说,如果结果超出您的位所能代表的范围,则会发生溢出.例如,如果将两个4位数字0111(7)和0010(2)加在一起,则会出现溢出,因为结果(9)超出了4位数字可以表示的范围(-8到7) .如果您看一下算术:

    li $t1,3
    li $t2,1
    add $t3,$t1,$t2 -----> throws an arthimetic overflow exception
    addu $t3,$t1,$t2 ------> t3 = -4
    

    您可以看到,尽管没有对符号位进位,但结果仍然不正确.因此,这是一个溢出(MIPS将检测到它)。

    0111 (7) + 0010 (2) = 1001 (-7)

相关问题

  • 用于嵌入C#/。NET应用程序的脚本语言?
  • php:Magento产品分类