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

MIPS汇编素数判断及范围内素数输出循环实现问题

问题背景

需要实现MIPS汇编程序,功能如下:

  • 接收用户输入的整数
  • 判断该整数是否为素数
  • 若输入为素数,同步输出所有不大于该输入值的素数
    示例:输入n=11时,预期输出为:11 is prime, and so are 2, 3, 5, 7, 11
    现有实现无法正确构建循环逻辑,无法完成输入值之前所有数字的素性校验,也无法正确执行输出/跳过的分支操作,原有代码如下:
.data 
    string1: .asciiz  "Please enter an integer: "
    string2: .asciiz  "Input is a prime number" 
    string3: .asciiz  "Input is not a prime number" 
    string4: .asciiz  "   "
    string5: .asciiz  "Prime numbers up to the input are: " 

.text 

main: 

    # Print string 1 
    la $a0, string1 
    li $v0, 4 
    syscall 
    
    # Take input from user 
    li $v0, 5 
    syscall 
    
    # Store input in temp register 
    move $t8, $v0 
    
    # Initial value for processing
    li $t9, 2 
    
    # Corner cases 
    blt $t8, 1, NotPrime 
    beq $t8, 1, NotPrime
    beq $t8, 2, Prime
    
    loopPrime: 
        beq $t9, $t8, Prime  # Branch to prime when input equals initial value 
        div $t8, $t9  # Divide input by numbers in range 
        mfhi $t1 # Move division remainder to t1
        beq $t1, $0, NotPrime  # If remainder equals 0, the input is not prime number 
        addi $t9, $t9, 1 # Increment initial value by 1 
        b loopPrime
        
Prime: 
    li $v0, 4 
    la $a0, string2 
    syscall 
    
    li $v0, 4 
    la $a0, string4 
    syscall 
    
    li $v0, 4 
    la $a0, string5 
    syscall 
    
    # Initial value2 for processing 
    li $t7, 2 
    
    b loopfactor2
    
    b Exit

loopfactor1: 
    addi $t7, $t7,1
    b loopfactor2

loopfactor2: 
    beq $t9, $t7, Print 
    div $t7, $t9
    mfhi $t1 
    beq $t1, $0, Skip 
    addi $t9, $t9, 1
    blt $t7, $t8 loopfactor1
    
    b Exit 
    

Print: 

li $v0, 4 
move $a0, $t7
syscall

Skip: 

addi $t7, $t7,1 
b loopfactor2
            
NotPrime: 
    li $v0, 4 
    la $a0, string3 
    syscall 
    b Exit 

Exit: 
    li $v0, 10 
    syscall 
原有代码核心错误
  • 寄存器复用冲突:判断输入本身素性时t9作为除数,值累加到和输入相等后才跳转到Prime分支,后续遍历素数时没有重置t9为2,直接复用导致除数初始值完全错误。
  • 素数校验逻辑失效:遍历每个待判断数字时,没有将除数重置回初始值2,除数持续累加,导致后续所有数字的素性判断完全错误。
  • 系统调用错误:打印整数需要使用$v0=1的系统服务,原代码Print块中错误使用了打印字符串的服务号$v0=4,会触发内存访问错误或输出乱码。
  • 分支逻辑混乱:loopfactor1和loopfactor2跳转顺序颠倒,循环终止条件位置错误,会出现死循环、漏判、提前退出等问题。
  • 语法错误:分支指令blt $t7, $t8 loopfactor1缺少寄存器与标签之间的逗号,无法通过汇编器编译。
  • 输出格式不匹配:预置的提示字符串与需求要求的输出格式不符,也没有处理素数之间的分隔符。
修正后可运行代码
.data 
    prompt: .asciiz  "Please enter an integer: "
    prime_prefix: .asciiz  " is prime, and so are "
    not_prime_tip: .asciiz  " is not a prime number"
    sep: .asciiz ", "

.text 

# 素数判断函数:入参$a0=待判断数字,返回$v0=1为素数,$v0=0为非素数
is_prime:
    addi $sp, $sp, -8
    sw $ra, 4($sp)
    sw $s0, 0($sp)
    move $s0, $a0

    li $v0, 0
    blt $s0, 2, is_prime_ret  # 小于2的数不是素数
    li $v0, 1
    beq $s0, 2, is_prime_ret  # 2是素数
    andi $t0, $s0, 1
    beqz $t0, is_prime_ret    # 大于2的偶数不是素数

    li $t0, 3
is_prime_loop:
    mult $t0, $t0
    mflo $t1
    bgt $t1, $s0, is_prime_ret # 除数平方大于待判断数时,是素数
    div $s0, $t0
    mfhi $t1
    beqz $t1, is_prime_ret     # 余数为0则不是素数
    addi $t0, $t0, 2           # 除数步长为2,跳过偶数
    b is_prime_loop

is_prime_ret:
    lw $s0, 0($sp)
    lw $ra, 4($sp)
    addi $sp, $sp, 8
    jr $ra

main:
    # 打印输入提示
    la $a0, prompt
    li $v0, 4
    syscall

    # 读取用户输入存入$s0
    li $v0, 5
    syscall
    move $s0, $v0

    # 判断输入本身是否为素数
    move $a0, $s0
    jal is_prime
    beqz $v0, print_not_prime

    # 输入是素数,先打印输入值
    move $a0, $s0
    li $v0, 1
    syscall
    la $a0, prime_prefix
    li $v0, 4
    syscall

    # 遍历2到$s0,输出所有素数
    li $s1, 2          # $s1为当前遍历的数字
    li $s2, 0          # $s2标记是否已输出第一个素数,用于处理分隔符
print_all_prime:
    bgt $s1, $s0, prog_exit
    move $a0, $s1
    jal is_prime
    beqz $v0, next_iter
    # 当前数是素数,处理分隔符
    beqz $s2, no_sep
    la $a0, sep
    li $v0, 4
    syscall
no_sep:
    li $s2, 1
    move $a0, $s1
    li $v0, 1
    syscall
next_iter:
    addi $s1, $s1, 1
    b print_all_prime

print_not_prime:
    move $a0, $s0
    li $v0, 1
    syscall
    la $a0, not_prime_tip
    li $v0, 4
    syscall

prog_exit:
    li $v0, 10
    syscall
实现说明
  • 将素数判断逻辑封装为独立函数,遵循MIPS栈调用约定,避免寄存器复用冲突,减少重复代码。
  • 优化素数判断效率:提前排除小于2的数、2本身、偶数,后续仅用奇数做除数,且除到待判断数的平方根即可终止判断,相比原逻辑效率提升明显。
  • 主流程先判断输入本身的素性,非素数直接输出对应提示;素数则从2开始遍历到输入值,逐个校验素性后输出,自动处理逗号分隔格式,第一个输出的素数前不打印逗号。
  • 修正了所有语法错误、系统调用错误、分支跳转错误,输入11时可输出符合要求的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:45:41