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

QtSPIM下MIPS Assembly:无sqrt指令如何实现判别式开平方求整数根

QtSPIM环境下整数二次方程根计算实现

核心问题解决思路

你遇到的QtSPIM无硬件sqrt指令的问题,结合“输出整数根”的需求,完全不需要引入浮点运算逻辑:

  • 整数根成立的前置条件:判别式Δ = b² - 4ac必须为非负完全平方整数,否则不存在整数根
  • 自定义整数平方根函数即可覆盖所有场景,不需要依赖硬件运算指令,逐次枚举实现对新手友好,无复杂算法要求

现有代码的显性BUG修正

对照你当前的代码,存在几个会导致程序完全无法运行的逻辑错误:

  • 输入逻辑不匹配:原代码读入x1、x2作为区间值,但公式法求根的逻辑只需要二次项a、一次项b、常数项c三个参数,不需要区间输入,这也是判别式计算错误的根源之一
  • 判别式计算逻辑错误:原代码中mul $t6,$t1,0直接将4ac项置零,完全丢失常数项参与的计算,正确的判别式逻辑为Δ = b*b - 4*a*c
  • 分支跳转目标不匹配:判断Δ=0时跳转到isioi标签,但实际代码中定义的等根分支标签为iso,跳转触发后会直接跑飞
  • 缺失分支实现:代码中写了Δ<0时跳转到mikro的指令,但从未定义mikro标签对应的处理逻辑
  • 无效系统调用:mega分支中写完计算逻辑直接调用syscall,但未提前设置$v0的系统调用功能号,操作完全无意义

可直接运行的完整实现

.data
# 保留你原有的自定义提示字符串
msg_read_a: .asciiz"dwse arithmo a:"
msg_read_b: .asciiz"dwse arithmo b:"
msg_read_c: .asciiz"dwse arithmo c:"
msg_root1: .asciiz"Prwto riza: "
msg_root2: .asciiz"Deuteri riza: "
akuro: .asciiz"h sunartish den mhdenizetai"
midenizetai: .asciiz"h sunarthsh midenizetai"

.text 
main:
# 读入a值
li $v0,4
la $a0,msg_read_a
syscall
li $v0,5
syscall
move $s0,$v0  # $s0存储二次项系数a

# 读入b值
li $v0,4
la $a0,msg_read_b
syscall 
li $v0,5
syscall
move $s1,$v0  # $s1存储一次项系数b

# 读入c值
li $v0,4
la $a0,msg_read_c
syscall
li $v0,5
syscall
move $s2,$v0  # $s2存储常数项c

# 计算判别式Δ = b² - 4ac
mul $t0, $s1, $s1    # t0 = b²
mul $t1, $s0, $s2    # t1 = a*c
sll $t1, $t1, 2       # t1 = 4*a*c,用移位运算替代乘法减少指令开销
sub $t8, $t0, $t1    # t8 最终存储判别式Δ

# 将Δ传入自定义整数平方根函数计算
move $a0, $t8
jal int_sqrt
move $t9, $v0        # t9存储整数平方根结果

# 分支逻辑判断
blt $t8, 0, no_root  # Δ<0 无实整数根
beq $t9, -1, no_root # Δ不是完全平方数,无整数根

# Δ=0场景:仅存在一个相等实根
beq $t8, 0, single_root

# Δ>0场景:存在两个不同实根
# 计算x1 = (-b + sqrtΔ)/(2a)
sub $t2, $zero, $s1  # t2 = -b
add $t3, $t2, $t9    # t3 = -b + sqrtΔ
sll $t4, $s0, 1      # t4 = 2*a
div $t5, $t3, $t4    # t5 = x1
# 计算x2 = (-b - sqrtΔ)/(2a)
sub $t3, $t2, $t9    # t3 = -b - sqrtΔ
div $t6, $t3, $t4    # t6 = x2
# 输出两个根的结果
li $v0,4
la $a0,msg_root1
syscall
li $v0,1
move $a0,$t5
syscall
li $v0,4
la $a0,msg_root2
syscall
li $v0,1
move $a0,$t6
syscall
j exit

# 单相等根处理分支
single_root:
sub $t2, $zero, $s1
sll $t4, $s0, 1
div $t5, $t2, $t4
li $v0,4
la $a0,midenizetai
syscall
li $v0,1
move $a0,$t5
syscall
j exit

# 无整数根处理分支
no_root:
li $v0,4
la $a0,akuro
syscall
j exit

# 自定义整数平方根函数
# 入口参数:$a0 = 待开方的非负整数
# 返回值:$v0 = 整数平方根;输入负数或非完全平方数时返回-1
int_sqrt:
    bltz $a0, sqrt_neg  # 输入负数直接返回-1
    beq $a0, 0, sqrt_zero
    li $t0, 1           # 从s=1开始逐次枚举
sqrt_loop:
    mul $t1, $t0, $t0   # 计算当前枚举值的平方
    beq $t1, $a0, sqrt_find  # 匹配到完全平方数
    bgt $t1, $a0, sqrt_nofind # 平方值超过待开方数仍未匹配,说明不是完全平方数
    addi $t0, $t0, 1
    j sqrt_loop
sqrt_neg:
    li $v0, -1
    jr $ra
sqrt_zero:
    li $v0, 0
    jr $ra
sqrt_find:
    move $v0, $t0
    jr $ra
sqrt_nofind:
    li $v0, -1
    jr $ra

exit:
# 程序退出
li $v0, 10
syscall

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 07:24:03