You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MIPS中addiu操作溢出检查及斐波那契数列溢出终止实现问询

解决MIPS斐波那契数的溢出检查问题

先看你当前的代码,这里有两个核心问题:一是加法操作数搞错了(你用了索引值$t2来做加法,而不是前一个斐波那契数),二是用了addu无符号加法——它不会触发溢出标志,没法直接检测有符号数的溢出。我们一步步来修正:

第一步:修正加法逻辑与指令

首先,循环里要确保$t0$t1始终是前两个斐波那契数,然后用add指令(而非addu)来计算下一个数——add会在有符号数溢出时设置CPU的溢出标志位,这是我们检测溢出的关键:

loop:
    # $t0 = Fib(n-2), $t1 = Fib(n-1)
    add $t3, $t0, $t1  # 计算Fib(n),用add触发溢出标志

第二步:检测溢出

MIPS里有两种常用的溢出检测方式:

方式1:用专用溢出分支指令

直接用bov(Branch on Overflow)指令,一旦add触发溢出就跳转到退出逻辑:

bov overflow_exit  # 溢出则跳转到收尾流程

方式2:手动判断符号位(兼容部分汇编器)

如果你的环境不支持bov,可以通过符号位异或来判断:两个同号数相加,结果和原数异号就说明溢出:

xor $t4, $t0, $t1
    bgez $t4, no_overflow  # 两个数异号,相加不可能溢出
    xor $t4, $t0, $t3
    bgtz $t4, overflow_exit  # 结果与原数异号,溢出
no_overflow:

第三步:存储有效结果并更新状态

如果没有溢出,就把结果存入数组,然后更新循环所需的变量:

# 存储当前斐波那契数到数组
    sw $t3, 8($s0)  # 第一次循环存在偏移8的位置,后续用寄存器跟踪偏移更稳妥
    # 更新前两个数,为下一次循环做准备
    move $t0, $t1
    move $t1, $t3
    # 更新计数(已计算的斐波那契数总数)
    addi $t2, $t2, 1
    # 更新数组偏移(建议用单独寄存器$t4跟踪,避免重复计算)
    addi $t4, $t4, 4
    j loop

第四步:溢出时的收尾工作

当溢出发生时,把最终的有效斐波那契数个数存入NUM_FBN,然后退出程序:

overflow_exit:
    sw $t2, NUM_FBN  # 存储有效斐波那契数的总数
    # MIPS退出系统调用
    li $v0, 10
    syscall

完整修正后的代码片段

整合所有逻辑后的完整代码如下:

.data
FBN: .space 400       # 最多存储100个4字节的斐波那契数
.align 2
NUM_FBN: .space 4     # 存储有效斐波那契数的个数
.align 2

.text
.globl main
main:
    la $s0, FBN
    li $t0, 0          # Fib(0)
    li $t1, 1          # Fib(1)
    sw $t0, 0($s0)
    sw $t1, 4($s0)
    li $t2, 2          # 已存储2个有效数(Fib(0)和Fib(1))
    li $t4, 8          # 下一个存储位置的偏移量

loop:
    add $t3, $t0, $t1  # 计算下一个斐波那契数
    bov overflow_exit  # 检测溢出,溢出则退出

    # 存储结果到数组
    sw $t3, ($t4)($s0)
    # 更新前两个数
    move $t0, $t1
    move $t1, $t3
    # 更新计数和偏移
    addi $t2, $t2, 1
    addi $t4, $t4, 4
    # 额外检查数组是否存满(可选)
    ble $t4, 396, loop  # 400字节的最后一个有效位置是396($s0)

overflow_exit:
    sw $t2, NUM_FBN
    li $v0, 10
    syscall

关键注意点

  • add而非adduaddu是无符号加法,即使溢出也不会设置溢出标志,不适合斐波那契数这类有符号整数的计算。
  • 计数初始值:初始已存储Fib(0)和Fib(1),所以计数$t2要从2开始,这样最终NUM_FBN的值才是有效数的总数。
  • 数组偏移跟踪:用单独的寄存器$t4跟踪存储位置,避免每次手动计算偏移出错。

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

火山引擎 最新活动