assembly MIPS中使用addu检测溢出

xwbd5t1u  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(118)

我正在努力在MIPS中实现检测溢出并使用addu抛出错误。
这是一个学校作业。我们得到的代码是一个非常基本的银行分类账。分类账要求用户输入,然后如果它是积极的,它会添加到余额,如果它是消极的,它会从余额中减去。我已经改进了它,以检测非整数输入,根据作业,现在我需要能够检测溢出并抛出错误消息,如果检测到溢出,则不更改余额(然后重新提示交易)。我在这里计算,因为这只是加法,如果符号相同并导致相反的符号,那么就有溢出。我还计算,如果符号相反,那么就不会发生溢出。
目前它似乎跳过了我的溢出检测,所以它工作,但没有检测溢出,因为我需要的分配。任何建议,我做错了什么?
下面是我的代码的相关部分:

loopB:
    li  $s1, 0          #### reset $s1
    add $s1, $zero, $t3     #### load integer value into $s1
    beqz    $s1, done       # If $s1 equals zero, branch to done
    li  $s2, 0          #### initialize $s2 for temporary balance
    addu    $s2, $s0, $t6       #### set temporary balance to initial balance
    addu    $s2, $s0, $s1       # add transaction amount to the temporary Balance

oTest:
    sltiu   $t6, $s0, 0     #### if $t6 == 1 then number is negative
    sltiu   $t7, $s1, 0     #### if $t7 == 1 then number is negative
    
    bne $t6, $t7, LoopC     #### if opposite signs then no overflow
    
    sltiu   $t8, $s2, 0     #### if $t8 == 1 then the number is negative
    
    and $t9, $t6, $t7       #### if $t9 == 1 then $t6 and $t7 are both negative
    
    bne     $t9, $t8, over      #### if $t9 and $t8 are not both negative, then overflow has occured
    
    sgtu    $t6, $s0, $zero     #### if $t6 == 1 then number is positive
    sgtu    $t7, $s0, $zero     #### if $t7 == 1 then number is positive
    sgtu    $t8, $s0, $zero     #### if $t8 == 1 then number is positive
    
    and $t9, $t6, $t7       #### if $t9 == 1 then $t6 and $t7 are both positive
    
    bne $t9, $t8, over      #### if $t8 and $t9 are not equal then overflow has occured

LoopC:
    addu    $s0, $s0, $s1       #### add transaction to balance
    li  $v0, 4          # system call code for print_string
    la  $a0, tabs       # load address of tabs into $a0
    syscall             # used to space over to the Balance column
    
    li  $v0, 1          # system call code for print_integer
    move    $a0, $s0        # move Bank Balance value to $a0 
    syscall             # print Bank Balance
    
    b   loop            # branch to loop
    
over:
    li  $v0, 4          #### system call code for print_string
    la  $a0, oMsg       #### load address of msg. into $a0
    syscall             #### print the string
    
    li  $s2, 0          #### reset $s2
    
    li  $v0, 1          #### system call code for print_integer
    move    $a0, $s0        #### move Bank Balance value to $a0 
    syscall             #### print Bank Balance
    
    b   loop            # branch to loop

字符串

x7yiwoj4

x7yiwoj41#

你能解释一下你想做什么吗:

addu    $s2, $s0, $t6       #### set temporary balance to initial balance
    addu    $s2, $s0, $s1       # add transaction amount to the temporary Balance

字符串

这两条指令在一起没有意义。第二条指令擦除/重置$s2,而不使用第一条指令的结果。
你正在使用unsigned compare来比较小于0的立即数--这将总是产生false,因为根据unsigned numbers的定义,没有unsigned numbers小于0。换句话说,negative是不可能用于unsigned numbers的属性。
如果你想知道这个数字是否为负数,请使用 signed 比较。
仅供参考,您还可以使用移位来提取或复制符号位,因此使用算术移位31,得到-1或0,并使用逻辑移位31得到1或0。
从根本上讲,你处理的是有符号整数,所以所有的比较操作都应该有符号,除非你真的知道那里有什么不同。
然而,* 你是对的,你需要做无符号加法和/或减法,以避免处理器的自动有符号溢出检测 *,因为如果你击中它将终止你的程序。当没有溢出时,无符号加法将产生相同的数字,相同的数值,相同的位模式作为有符号加法,所以,这是有效的。-如果有溢出,你可以在你思考的时候检测到它,例如在加法之后。
但是比较需要用有符号的算术来完成,这样才有意义,而且这些有符号的比较(不像有符号的加法/减法)不会有碰到处理器溢出陷阱的风险。

相关问题