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

汇编质数打印程序无输出问题排查及代码修改建议

问题排查与修改方案

核心问题分析

1. 质数打印循环的退出逻辑完全失效

你在showPrimes中用ECX同时承担了每行打印计数和总质数计数两个角色,导致循环无法终止:

  • 当打印满10个质数后,ECX被重置为0,此时判断CMP ECX, EBX(用户输入的质数数量≥1)永远成立,程序陷入无限循环。
  • 退出判断的位置错误,应该在每次找到质数并更新总计数后检查是否达到用户要求,而非换行重置行计数之后。

2. isPrime函数的逻辑错误

  • DIV指令会破坏原始的EAX值(待检查的数),导致后续判断出错。比如检查2时,执行DIV 2后EAX变为1,会误判为非质数。
  • 质数边界判断错误:当除数等于待检查数时(如2÷2),余数为0,但这是质数的合法情况,不能直接判定为非质数。

修改方案

1. 修复showPrimes的循环逻辑

新增寄存器EDI记录已找到的总质数数量,ECX仅用于每行计数,调整退出判断的位置:

showPrimes PROC
    MOV     EBX, userInput  ; EBX = 用户要求的质数数量
    MOV     ECX, 0          ; ECX = 每行已打印的质数计数
    MOV     EDI, 0          ; EDI = 已找到的总质数计数
    MOV     EAX, 2          ; 从第一个质数2开始检查

printPrime:
    PUSH    EAX             ; 保存当前要检查的数
    CALL    isPrime         
    POP     EAX             ; 恢复原数
    
    CMP     EAX, 1          ; 判断是否为质数
    JNE     notPrime        ; 非质数则跳过
    
    ; 打印质数
    CALL    WriteDec
    MOV     EDX, OFFSET spacer
    call    WriteString
    INC     ECX             ; 行计数+1
    INC     EDI             ; 总计数+1

    ; 检查是否达到用户要求的数量,达到则退出
    CMP     EDI, EBX
    JE      exitShowPrimes

    ; 每行满10个则换行并重置行计数
    CMP     ECX, 10         
    JNE     nextPrime       
    CALL    CrLf
    MOV     ECX, 0          

nextPrime:
    INC     EAX             
    JMP     printPrime

notPrime:
    INC     EAX 
    JMP     printPrime

exitShowPrimes:
    CALL    CrLf  ; 最后一行换行,格式更整齐
    ret
showPrimes ENDP

2. 修复isPrime函数的逻辑

保存原始待检查数,修正边界判断逻辑,同时优化检查效率:

isPrime PROC
    ; 处理边界情况:2是质数
    CMP     EAX, 2
    JE      prime

    ; 小于2的数不是质数
    CMP     EAX, 1      
    JLE     notPrime

    ; 偶数(除了2)不是质数
    TEST    EAX, 1
    JE      notPrime

    MOV     EBX, EAX        ; EBX保存原始要检查的数
    MOV     ECX, 3          ; 从3开始检查奇数除数,提高效率

checkDivisor:
    MOV     EDX, 0
    MOV     EAX, EBX
    DIV     ECX             ; 计算余数

    CMP     EDX, 0          ; 余数为0则非质数
    JE      notPrime

    INC     ECX             ; 只检查奇数,可优化为ADD ECX,2进一步提升效率
    CMP     ECX, EBX
    JGE     prime           ; 除数达到或超过原数,说明是质数

    JMP     checkDivisor

notPrime:
    MOV     EAX, 0
    ret

prime:
    MOV     EAX, 1
    ret
isPrime ENDP

3. 修正范围校验的严谨性

validate函数中,将JL valid改为JLE valid,确保用户输入等于200时也能被判定为有效:

validate PROC
    MOV     EBX, userInput
    CMP     EBX, LOWER_BOUND
    JL      rangeError
    
    CMP     EBX, UPPER_BOUND
    JG      rangeError
    JLE     valid  ; 改为JLE,包含等于200的情况

rangeError:
    MOV     EDX, OFFSET outOfRange
    call    WriteString
    JMP     ending

valid:
    MOV     EAX, 1
    MOV     validNum, EAX

ending:
    ret
validate ENDP

测试验证

修改后输入15,会输出前15个质数:

2   3   5   7   11   13   17   19   23   29   
31   37   41   43   47   
Results certified by Norman O'Brien. Goodbye.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 18:42:36