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

MIPS嵌套循环质数求解代码冻结故障排查求助

Hey there! Let's break down why your MIPS prime-finding code is freezing and fix those loop issues you're suspicious of—this is super common when getting started with MIPS assembly, so don't stress.

First: The Dead Loop That's Freezing Your Program

The biggest issue is your inner loop (L1) has no way to progress! Look at your code: once you enter L1, you never increment $t2 (the divisor you're checking). That means $t2 stays at whatever initial value you set it to (I assume $t6 is 2), and as long as that value is less than $t1, the blt $t2, $t1 L1 condition will always be true. Your program gets stuck spinning in this loop forever, hence the freeze.

You need to add an increment for $t2 inside the inner loop—right after your branch check at label I is perfect:

I: addi $t2, $t2, 1       # Increment divisor by 1 each loop iteration
    blt $t2, $t1 L1

Second: Prime-Checking Logic Gaps

Even once you fix the dead loop, your logic has a couple of tweaks to make it work correctly and efficiently:

  • Exit early when a divisor is found: Right now, if you find a number that divides $t1 (i.e., remu returns 0), you set $t3 but keep looping. There's no need to check further—if one divisor exists, the number isn't prime. Add a jump to exit the inner loop immediately after marking the non-prime flag:
    bne $t4, $zero, I
    move $t3, $t5         # Mark as non-prime
    j END_L1              # Jump out of inner loop right away
    I: addi $t2, $t2, 1
    
    Don't forget to add an END_L1 label after the inner loop to jump to.
  • Optimize the inner loop range: You don't need to check all the way up to $t1—checking up to $t1/2 (or even the square root of $t1) is enough. If a number n has a factor larger than n/2, the only possible factor is n itself (which we don't care about for primes). This cuts your loop iterations in half, making the program way faster.
  • Don't forget to increment $t1!: Looking at your outer loop, you never increment the number you're checking ($t1). That means you'll keep checking the same number forever, even after fixing the inner loop. Add an increment at the end of the outer loop before jumping back to L2:
    P: addi $t1, $t1, 1       # Move to the next number to check
        bgt $t1, $t0, E
        j L2
    

Fixed Code Snippet (Key Changes Highlighted)

Here's how your core loop should look with all these fixes:

#Outer loop
L2: move $t3, $zero       # Reset non-prime flag to 0
    move $t2, $t6         # Initialize divisor to 2 (ensure $t6 = 2!)
    # Calculate $t1/2 for optimized loop condition
    add $t7, $t1, $zero
    srl $t7, $t7, 1       # $t7 = $t1 divided by 2 (bit shift is faster than div)

# Inner loop
L1: remu $t4, $t1, $t2
    bne $t4, $zero, I
    move $t3, $t5         # Mark as non-prime
    j END_L1              # Exit inner loop early once divisor is found
I: addi $t2, $t2, 1       # ⚠️ Critical: Increment divisor to avoid dead loop
    blt $t2, $t7, L1      # Loop only up to $t1/2 (optimized condition)
END_L1:

    bne $t3, $zero, P
    # Print the prime number
    li $v0, 1
    move $a0, $t1
    syscall
    li $v0, 4
    la $a0, space
    syscall
P: addi $t1, $t1, 1       # ⚠️ Critical: Move to next number to check
    bgt $t1, $t0, E
    j L2
E: li $v0, 10
    syscall # call operating sys
end: jr $ra

Just double-check that your initial values are set correctly before entering L2: $t1 should start at 2 (the first prime), $t0 should be the upper limit of numbers you want to check, $t5 should be set to 1 (to mark non-primes), and $t6 should be 2 (the starting divisor).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:37:32