请教这段8086升序排序汇编代码的具体工作机制
8086汇编升序排序代码逻辑解析
待分析的排序代码
这段是实验室8086实验箱上演示的升序排序汇编代码(注:代码中存在一处明显笔误,已在解析中标注):
mov si, 2000 mov cl, [si] dec cl loop1: mov si, 2000 mov ch, [si] dec ch inc si loop2: mov al, [si] inc si cmp al, [si] jc loop3 xchg al, [si] dec si xchg al, [si] // 原代码写为xchg di, [si],属于笔误,否则交换逻辑断裂 inc si loop3: dec ch jnz loop2 dec cl jnz loop1 int a5
数组存储格式
假设N个无符号元素d1、d2…dN按如下格式存储(首地址为2000H):
| 地址 | 2000 | 2001 | 2002 | 2003 | ... | 2000+N | ... |
|---|---|---|---|---|---|---|---|
| 数据 | N | d1 | d2 | d3 | ... | dN | ... |
我的初步分析(卡壳点)
- 初始化:
mov si, 2000:SI指向数组长度的存储地址mov cl, [si]:CL存入数组长度Ndec cl:CL变为N-1,控制外层循环总次数
- 外层循环(loop1):
- 每次重置SI到2000H,读取数组长度N到CH,
dec ch后CH为N-1,控制内层循环次数 inc si:SI移动到第一个元素d1的地址(2001H)
- 每次重置SI到2000H,读取数组长度N到CH,
- 内层循环(loop2):
mov al, [si]:AL存入当前元素inc si:SI移动到下一个元素地址cmp al, [si]:比较当前元素与下一个元素- 若
jc loop3:CF=1时跳转(即当前元素小于下一个元素),无需交换直接进入下一轮比较 - 若不跳转(当前元素≥下一个元素),执行交换逻辑,但此处原代码的
xchg di, [si]让我无法继续跟进逻辑
- 内层收尾(loop3):
dec ch:内层计数器减1,非0则继续内层循环
想请教这段代码到底如何实现升序排序?实验室演示示例如下:
输入输出示例
| 地址 | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 | ... |
|---|---|---|---|---|---|---|---|
| 输入数据 | 5 | 04 | 03 | 01 | 00 | 02 | ... |
| 输出数据 | 5 | 00 | 01 | 02 | 03 | 04 | ... |
完整逻辑解析
这段代码本质是无符号数的基础冒泡排序,核心是通过两层循环,每轮内层循环将当前未排序部分的最大元素“冒泡”到末尾,最终实现升序排列。
关键指令与逻辑修正
JC指令:无符号数比较中,cmp al, [si]若al < [si]会产生借位(CF=1),此时jc loop3跳转,跳过交换逻辑,符合升序要求- 交换逻辑笔误修正:原代码
xchg di, [si]应为xchg al, [si],修正后才能完成两个相邻元素的交换:xchg al, [si]:将当前元素(存在AL)与下一个元素交换dec si:SI回到当前元素的原地址xchg al, [si]:将AL中保存的下一个元素写入当前元素的原地址,完成相邻元素交换inc si:SI回到下一个元素地址,继续后续比较
结合示例的完整执行流程
示例输入:数组长度N=5,元素为[04,03,01,00,02](地址2001~2005)
- 外层第1轮(CL=4):
内层循环遍历所有相邻元素,将最大元素04冒泡到末尾,数组变为[03,01,00,02,04] - 外层第2轮(CL=3):
内层循环遍历,将次大元素03冒泡到倒数第二位置,数组变为[01,00,02,03,04] - 外层第3轮(CL=2):
内层循环遍历,将元素01与00交换,数组变为[00,01,02,03,04] - 外层第4轮(CL=1):
内层循环遍历所有元素,无交换发生,排序完成
代码特点
这是未优化的冒泡排序实现,每轮内层循环都会完整遍历所有相邻元素,即使数组提前有序仍会执行完所有外层循环,逻辑简单直观,适合教学演示。
内容的提问来源于stack exchange,提问作者Awe Kumar Jha
相关产品推荐
相关产品推荐

