You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将C代码转为MIPS汇编时出现算术溢出异常的求助

分析MIPS汇编中算术溢出异常的原因及修复方案

首先明确你的场景:你要把这段C代码转换为MIPS汇编:

int call(int arg) { 
    return foo(arg+10) + bar(arg) + baz(one(), two(arg-1), arg); 
}

你的MIPS实现运行时在add $s0, $s0, $v0这一行触发了算术溢出异常,下面是具体的原因分析和解决办法:

一、溢出异常的直接原因

MIPS的add指令是带符号溢出检查的加法指令。当你用它计算两个有符号整数的和时,如果结果超出了32位有符号整数的取值范围(即大于0x7FFFFFFF或小于0x80000000),CPU就会触发算术溢出异常。

你这行代码是在累加foo(...) + bar(...) + baz(...)的结果,当这三个函数返回值的总和超出32位有符号整数范围时,add指令就会抛出这个异常。

二、额外的代码规范问题(影响稳定性)

除了溢出问题,你的代码还有一个不符合MIPS ABI(应用二进制接口)的问题:
你直接使用了$s0和$s1这两个保存寄存器(callee-saved registers),但没有在函数开头将它们的值保存到栈上,也没有在函数返回前恢复。根据MIPS的调用约定,这类寄存器的值需要被函数保留,如果你直接修改它们,会破坏调用者的寄存器上下文,可能导致其他不可预期的错误。

三、具体的修复方案

方案1:替换为无溢出检查的加法指令

如果你不需要对溢出进行检查(比如业务逻辑允许结果溢出后按二进制回绕,或者你处理的是无符号整数),可以把所有的add指令替换为addu(无溢出检查的加法):

# 替换原来的add指令
addu $s0, $v0, $zero # s0 = foo(arg+10)
addu $s0, $s0, $v0 # s0 = foo(...) + bar(...)
addu $s0, $s0, $v0 # s0 = 三个函数返回值的总和
addu $v0, $s0, $zero

addu指令不会检查溢出,即使结果超出有符号范围,也只会按二进制位的方式计算结果,不会触发异常。

方案2:处理溢出(如果需要确保结果合法)

如果你需要保证结果在有符号整数范围内,那么需要在加法前手动检查溢出情况:
比如,在执行add之前,检查两个操作数的符号:

  • 如果两个正数相加结果为负数,或者两个负数相加结果为正数,就说明会溢出,此时可以加入对应的错误处理逻辑(比如设置错误码、终止程序等)。

方案3:修复寄存器保存问题

按照MIPS ABI规范,使用$s0和$s1前需要先保存它们的值到栈上,函数结束时恢复:

.globl callMany
callMany:
    # 保存$s0、$s1到栈上(因为我们要修改它们)
    addiu $sp, $sp, -12 
    sw $s0, 0($sp)
    sw $s1, 4($sp)
    
    # 原业务逻辑
    add $s1, $a0,$zero
    addi $a0, $a0, 10
    jal foo
    addu $s0, $v0, $zero #s0 = foo(arg+10)
    
    add $a0, $s1, $zero
    jal bar
    addu $s0, $s0, $v0 #s0 = foo(arg+10)+bar(arg)
    
    addiu $sp, $sp, -8
    jal one
    sw $v0, 0($sp) #save one()
    
    addi $a0, $s1, -1
    jal two
    sw $v0, 4($sp) #save two(arg-1)
    
    lw $a0, 0($sp)
    lw $a1, 4($sp)
    addiu $sp, $sp, 8
    
    add $a2, $s1, $zero
    jal baz
    addu $s0, $s0, $v0 # 用addu避免溢出异常
    addu $v0, $s0, $zero
    
    # 恢复$s0、$s1
    lw $s1, 4($sp)
    lw $s0, 0($sp)
    addiu $sp, $sp, 12
    
    jr $ra

内容的提问来源于stack exchange,提问作者Jinfan Hu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:43:41