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

32位NASM汇编实现整数升序排序:cmp比较不设置标志位问题求解

问题排查与解决方法

核心问题说明

你的代码存在3个关键错误导致比较逻辑不生效:

  1. 输入数据类型错误
    SYS_READ(int 80h的3号调用)读取到的输入是ASCII字符串序列,比如输入123,内存中存储的是0x31、0x32、0x33、0x0a(换行符),并不是可以直接比较的二进制整数,直接对比这些值无法得到数字本身的大小关系。
  2. 寄存器加载逻辑错误
    你写的mov eax, input1是把input1缓冲区的内存起始地址赋值给了eax,并不是把缓冲区存储的内容加载到寄存器,你后续比较的实际是三个输入缓冲区的地址大小,和输入的数值完全无关,所以标志位变化和输入无关。
  3. 交换逻辑bug
    以swap2_3的代码为例:
push ebx
mov ecx, ebx
pop ecx

这段代码执行后ecx会被直接覆盖为ebx的值,原来的ecx值完全丢失,没有实现交换效果。

解决方案

第一步:字符串转整数

你需要先将读取到的ASCII字符串转换为32位二进制整数再做比较,你引入的functions.asm通常内置了atoi(ASCII转整数)函数,调用方式为将字符串地址传入eax,转换完成的整数会返回在eax中:

; 转换三个输入为整数,分别存入esi、edi、edx
mov eax, input1
call atoi
mov esi, eax

mov eax, input2
call atoi
mov edi, eax

mov eax, input3
call atoi
mov edx, eax

第二步:修正排序逻辑

可以直接用更简单的冒泡逻辑实现三个数的升序排序,用xchg指令简化交换操作,不需要额外用栈操作:

ascend_sort:
    ; 保证第一个数<=第二个数
    cmp esi, edi
    jle check_second_third
    xchg esi, edi
check_second_third:
    ; 保证第二个数<=第三个数
    cmp edi, edx
    jle sort_finish
    xchg edi, edx
    ; 交换后可能第一个数大于新的第二个数,重新走一遍检查
    jmp ascend_sort
sort_finish:
    ; 此时 esi <= edi <= edx,就是升序排序后的结果
    jmp continue

第三步:结果输出

输出时需要将整数转回ASCII字符串再打印,functions.asm一般也内置了iprint(直接打印整数)或者itoa(整数转ASCII)函数,直接调用即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 02:09:01