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

汇编语言cmp指令无法正常工作问题求助(附代码)

问题分析与修复方案

咱们先拆解下你的汇编代码里几个核心问题——这些都是导致cmp指令没按预期工作的根源:

1. 错误加载内存地址而非输入数值

你写的mov ax, number1其实是把number1缓冲区的内存地址塞进了ax寄存器,而不是用户输入的数字内容。要读取内存里的实际值,得用mov ax, [number1](别漏了方括号)。但这还不够,更大的问题在下面:

2. 未将ASCII输入转为二进制数值

用户通过int 80h(sys_read)输入的是ASCII字符串,比如输入"12",内存里存的是0x31 0x32 0x0A(最后是换行符),直接拿这些ASCII码去比较完全不对,必须先把字符串转换成二进制整数。

3. 分支逻辑与系统调用错误

你的jl _ss1之后直接执行_ss1的代码,但没处理number1 >= number2的情况;而且_ss1里的int 80h没设置eax等寄存器,会触发错误的系统调用。


修复后的完整代码

我给你调整好了可正常运行的版本,关键修改都加了注释:

global _start

section .bss
    number1: resb 3    ; 存储输入的ASCII字符串(最多2位数字+换行)
    number2: resb 3

section .data
    label1 db "enter the first number >>>", 0ah
    len equ $-label1
    label2 db "enter the second number >>>", 0ah
    len2 equ $-label2
    mess1 db "number 1 less than number 2", 0ah
    l1 equ $-mess1
    mess2 db "number 2 less than number 1", 0ah
    l2 equ $-mess2
    mess_eq db "numbers are equal", 0ah
    l_eq equ $-mess_eq

section .text
_start:
    ; 提示输入第一个数字
    mov eax,4
    mov ebx,1
    mov ecx,label1
    mov edx,len
    int 80h

    ; 读取第一个数字(最多3字节:2位数字+换行)
    mov eax,3
    mov ebx,0          ; 注意:标准输入的文件描述符是0,不是2!2是标准错误
    mov ecx,number1
    mov edx,3
    int 80h

    ; 提示输入第二个数字
    mov eax,4
    mov ebx,1
    mov ecx,label2
    mov edx,len2
    int 80h

    ; 读取第二个数字
    mov eax,3
    mov ebx,0
    mov ecx,number2
    mov edx,3
    int 80h

    ; 把ASCII字符串转成二进制数值
    mov ebx, number2
    call ascii_to_num
    mov cx, ax         ; 把number2的数值暂存在cx

    mov ebx, number1
    call ascii_to_num
    ; 现在ax是number1的数值,cx是number2的数值

    ; 执行数字比较
    cmp ax, cx
    jl print_less      ; number1 < number2
    jg print_greater   ; number1 > number2
    jmp print_equal    ; 两数相等的情况

print_less:
    mov eax,4
    mov ebx,1
    mov ecx,mess1
    mov edx,l1
    int 80h
    jmp exit

print_greater:
    mov eax,4
    mov ebx,1
    mov ecx,mess2
    mov edx,l2
    int 80h
    jmp exit

print_equal:
    mov eax,4
    mov ebx,1
    mov ecx,mess_eq
    mov edx,l_eq
    int 80h

exit:
    ; 退出程序
    mov eax,1
    mov ebx,0
    int 80h

; 子程序:将ASCII字符串转为16位二进制数
; 输入:ebx = 字符串地址(最多2位数字,结尾是换行)
; 输出:ax = 转换后的数值
ascii_to_num:
    xor ax, ax         ; 初始化ax为0
    mov cl, [ebx]      ; 取第一位字符
    sub cl, '0'        ; ASCII转数字
    mov al, cl
    mov cl, [ebx+1]    ; 取第二位字符
    cmp cl, 0ah        ; 判断是不是换行符(输入1位数字的情况)
    je .single_digit
    sub cl, '0'
    mov bl, 10
    mul bl             ; ax = ax * 10
    add ax, cx
.single_digit:
    ret

关键修改说明

  • 标准输入修正:原来的mov ebx,2是错误的,标准输入的文件描述符是0,2是标准错误输出,这会导致读取输入失败。
  • ASCII转数值子程序:新增ascii_to_num把输入的字符串转成二进制整数,这样cmp才能正确比较数字大小。
  • 分支逻辑完善:用jl/jg/jmp覆盖了所有比较情况,每个分支执行输出后都会跳转到退出逻辑,避免代码混乱。
  • 内存读取修正:用mov cl, [ebx]这种带方括号的语法读取内存中的字符,而非直接加载地址。

这样修改后,你的数字比较逻辑就能正常工作了!

内容的提问来源于stack exchange,提问作者Robert Kemalettin Connor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:30:03