32位NASM汇编实现整数升序排序:cmp比较不设置标志位问题求解
问题排查与解决方法
核心问题说明
你的代码存在3个关键错误导致比较逻辑不生效:
- 输入数据类型错误
SYS_READ(int 80h的3号调用)读取到的输入是ASCII字符串序列,比如输入123,内存中存储的是0x31、0x32、0x33、0x0a(换行符),并不是可以直接比较的二进制整数,直接对比这些值无法得到数字本身的大小关系。 - 寄存器加载逻辑错误
你写的mov eax, input1是把input1缓冲区的内存起始地址赋值给了eax,并不是把缓冲区存储的内容加载到寄存器,你后续比较的实际是三个输入缓冲区的地址大小,和输入的数值完全无关,所以标志位变化和输入无关。 - 交换逻辑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
相关产品推荐
相关产品推荐

