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

请求修复x86(32位)汇编程序:输出1-100000的质数

我帮你排查了这段x86 32位汇编代码里的问题,主要涉及语法错误、质数判断逻辑漏洞和系统调用误用几个方面,下面是修正后的代码和详细的错误说明:

原代码的核心错误点

  • div指令语法错误:x86的div是单操作数指令,原代码里的div edx, edx是无效写法,正确用法是用EDX:EAX作为被除数,操作数作为除数,余数会存在EDX中。
  • 质数判断逻辑混乱:
    • 从eax=1开始,但1不是质数,应该从2起步;
    • 检查新数字时没有重置除数edx,导致后续判断复用旧的除数,逻辑错误;
    • 没有优化判断终止条件(可以在除数平方超过当前数时停止,提升效率)。
  • 打印功能完全错误:
    • 用了eax=3(read系统调用)而不是eax=4(write)来打印;
    • 直接把数字传入ecx,但write要求ecx指向内存中的ASCII字符串,数字必须先转换为字符串才能打印;
    • 打印完一个数后直接退出,没有继续查找后续质数。

修正后的代码

section .data
    msg db 'The next prime number is: ', 0xA  ; 添加换行符,输出更清晰
    len equ $-msg
    num_buf db '00000', 0xA  ; 存储转换后的数字字符串(最多5位,加换行)
    buf_len equ $-num_buf

section .text
    global _start

_start:
    mov eax, 2          ; 从第一个质数2开始
    mov ecx, 100000     ; 上限值100000

find_next_prime:
    cmp eax, ecx
    jg exit_program     ; 超过上限则退出程序

    ; 保存当前数字到栈上(因为mul/div会覆盖eax)
    push eax
    mov edx, 2          ; 除数从2开始试除
check_divisor:
    mov ebx, edx
    mul ebx             ; edx:eax = edx * edx(除数的平方)
    cmp eax, [esp]      ; 比较除数平方和原数字
    jg is_prime         ; 除数平方>原数字,说明是质数

    mov eax, [esp]      ; 恢复原数字
    xor edx, edx
    div ebx             ; 原数字除以除数,余数存edx
    cmp edx, 0
    je next_number      ; 余数为0,不是质数,跳去下一个数

    inc edx             ; 除数加1,继续试除
    jmp check_divisor

is_prime:
    mov eax, [esp]      ; 恢复原质数
    ; 打印提示信息
    mov eax, 4
    mov ebx, 1
    mov ecx, msg
    mov edx, len
    int 0x80

    ; 转换质数为ASCII字符串并打印
    push eax
    call num_to_str
    add esp, 4

    mov eax, 4
    mov ebx, 1
    mov ecx, num_buf
    mov edx, buf_len
    int 0x80

next_number:
    pop eax             ; 弹出栈中保存的数字
    inc eax             ; 检查下一个数
    jmp find_next_prime

exit_program:
    mov eax, 1
    xor ebx, ebx
    int 0x80

; 辅助函数:将整数转换为ASCII字符串
; 输入:eax = 待转换的整数
; 输出:num_buf中存储对应的ASCII字符串(带换行)
num_to_str:
    mov ebx, num_buf + buf_len - 2  ; 从字符串末尾(换行前)开始填充
    mov ecx, 10                     ; 十进制除数

convert_loop:
    xor edx, edx
    div ecx                         ; eax = 商,edx = 余数
    add dl, '0'                     ; 余数转换为ASCII字符
    mov [ebx], dl
    dec ebx
    cmp eax, 0
    jne convert_loop                ; 直到商为0,转换完成
    ret

关键修改说明

  1. 质数判断优化:新增了栈存储原数字的逻辑,避免mul/div覆盖寄存器值;当除数的平方超过当前数字时,直接判定为质数,大幅提升效率。
  2. 数字转换功能:新增num_to_str函数,通过逐位取余的方式将整数转换为ASCII字符串,解决了直接打印数字的错误。
  3. 流程控制修复:打印完一个质数后,回到循环继续查找下一个数,直到超过100000才退出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 10:16:36