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

汇编语言质数判断程序始终输出相同结果的问题排查

汇编质数判断代码的问题分析

我正在学习汇编语言(ASM),这是我尝试解决的问题之一。该算法目标是判断一个数是否为质数,我逻辑推演认为代码应可行,但实际运行时无论输入数值如何,输出结果始终一致。若是其他编程语言,我可通过添加打印语句调试,但汇编语言无法如此操作,希望有人帮忙分析问题原因。我尝试修改循环条件,但仅改变了固定输出的内容,并未解决输出始终一致的问题。

我的代码如下:

section .data
    number db 15 ; 
    answer db 1 ; 1 -> prime, 0 -> not prime
    prime_msg db 'Number is prime', 0x0a
    not_prime_msg db 'Number is NOT prime', 0x0a
    
    section .bss
    divisor resb 1 ; Reserve one byte for the divisor
    
    section .text
    global _start
    
    _start: 
        mov al, [number]
        mov bl, 2 ; divisor = 2
    
    while_loop:
        cmp bl, al
        jg end  ;if number (al) is < divisor(bl) jump to end
        
        mov dl, al ; Move number into DL
        mov al, bl ; Move divisor into AL
         
        xor ah, ah ;clear remainder
        div bl     ;div al by bl(divisor)
        
        cmp ah, 0  ;compare remainder to 0
        je not_prime ;jump to not_prime if 0
        
        inc bl 
        jmp while_loop
        
    not_prime:
        mov byte [answer], 0
        
    out_not:
        mov edx, 16 ; Length of prime_msg ('Number is prime\n')
        mov ecx, prime_msg ; Pointer to prime_msg
        mov ebx, 1 ; File descriptor for stdout
        mov eax, 4 ; sys_write system call
        int 0x80 ; Make the system call
    
        ; Exit the program
        mov eax, 1 ; sys_exit system call
        xor ebx, ebx ; Return code 0
        int 0x80 ; Make the system call
        
    out_prime:
        mov edx, 20 ; Length of not_prime_msg
        mov ecx, not_prime_msg ; Pointer to not_prime_msg
        mov ebx, 1 ; File descriptor for stdout
        mov eax, 4 ; sys_write system call
        int 0x80 ; Make the system call
    
        ; Exit the program
        mov eax, 1 ; sys_exit system call
        xor ebx, ebx ; Return code 0
        int 0x80 ; Make the system call
        
    end:
        cmp byte[answer], 0 
        je out_not ;if answer = 0 -> not prime
        
        jmp out_prime ;else prime

问题分析

你的代码存在几个关键错误,导致输出始终一致:

  1. 除法逻辑完全错误:
    你原本想计算number ÷ divisor,但代码里先把al(存储number)移到dl,然后把bl(divisor)赋值给al,接着执行div bl——这相当于用divisor除以它自己,余数必然是0,所以每次循环都会触发je not_prime跳转,直接设置answer为0。
    正确的做法是保留al中的number值,清空ah后执行div bl,这样才是用number除以divisor。

  2. 循环条件被破坏:
    你在循环里修改了al的值(mov al, bl),导致后续cmp bl, al的判断完全失效——此时al已经等于bl,循环条件永远不满足jg end,除非你手动修改,但这也会让逻辑彻底混乱。

  3. 流程跳转与输出逻辑搞反:
    在not_prime标签设置answer为0后,代码直接进入out_not执行输出,但out_not里输出的是prime_msg;同时end标签的判断中,je out_not指向的输出也是错误的——out_not输出质数消息,out_prime输出非质数消息,完全颠倒了逻辑。

修正后的代码示例

section .data
    number db 15 ; 测试用的数字
    answer db 1 ; 1 -> 质数, 0 -> 非质数
    prime_msg db 'Number is prime', 0x0a
    not_prime_msg db 'Number is NOT prime', 0x0a
    prime_len equ $ - prime_msg
    not_prime_len equ $ - not_prime_msg
    
section .text
global _start
    
_start: 
    mov al, [number]
    ; 处理特殊情况:小于2的数不是质数
    cmp al, 2
    jl set_not_prime
    mov bl, 2 ; 从2开始试除
    
while_loop:
    ; 优化:只需要试除到number/2即可,减少循环次数
    mov cl, 2
    mov al, [number]
    div cl
    cmp bl, al
    jg end_loop
    
    mov al, [number]
    xor ah, ah ; 清空ah,确保ax是完整的number值
    div bl     ; ax ÷ bl,余数存在ah中
    
    cmp ah, 0
    je set_not_prime ; 余数为0,说明不是质数
    
    inc bl
    jmp while_loop
    
set_not_prime:
    mov byte [answer], 0
    
end_loop:
    cmp byte [answer], 0
    je print_not_prime
    
print_prime:
    mov edx, prime_len
    mov ecx, prime_msg
    mov ebx, 1
    mov eax, 4
    int 0x80
    jmp exit_program
    
print_not_prime:
    mov edx, not_prime_len
    mov ecx, not_prime_msg
    mov ebx, 1
    mov eax, 4
    int 0x80
    
exit_program:
    mov eax, 1
    xor ebx, ebx
    int 0x80

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 22:30:37