基于Emu8086的冒泡排序代码问题:按流程图实现后无效果
8086冒泡排序代码无变化问题排查
以下是导致数组无变化的核心错误及修正方案:
1. 数组地址完全不匹配
需求明确数组起始地址为200h,但代码存在两处矛盾:
- data段中
tab数组默认从偏移0h开始存储,而非200h - 代码中
mov si,200h操作的是DS段(已指向data段)的200h偏移位置,这和tab数组的实际存储地址完全无关,相当于操作了空白内存,tab数组根本没被处理
修正方案:二选一即可
- 在data段开头添加
org 200h,让tab数组从200h偏移开始存储:data segment org 200h tab db 30h,35h,23h,37h,38h,39h,31h n dw 7 ends - 或者让SI指向
tab数组的实际偏移:把mov si,200h改成mov si, offset tab
2. SI被错误赋值为元素值
交换元素后,你写了mov si,ax,这是完全错误的操作:
- SI是地址寄存器,应该存储数组的偏移地址,而AL是当前元素的值,把元素值赋值给SI会让SI指向一个随机的内存位置,后续所有操作都偏离了数组范围
修正方案:直接删除mov si,ax这一行,交换逻辑完成后,con标签里的inc si会正确移动到下一个元素地址。
3. 外层循环跳转目标错误
内层循环结束后,你用jnz bcl跳转到内层循环的标签,这会导致程序无法回到外层循环的etq标签重新初始化DX、SI等寄存器,外层循环逻辑完全失效。
修正方案:把jnz bcl改成jnz etq,让程序回到外层循环的开头。
4. AL的更新逻辑缺失
冒泡排序需要逐对比较连续元素,你只在一开始执行了mov al,[si],后续每次inc si后,AL仍然保留之前的元素值,导致后续比较的是旧元素和新位置的下一个元素,完全不符合排序逻辑。
修正方案:在con标签的inc si之后,添加mov al,[si],确保每次循环都用当前SI位置的元素参与比较:
con: inc si mov al,[si] ; 添加这行,更新AL为当前SI指向的元素 dec dx jnz bcl
修正后的完整代码示例
; multi-segment executable file template. data segment org 200h ; 让tab从200h偏移开始 tab db 30h,35h,23h,37h,38h,39h,31h n dw 7 ends stack segment dw 128 dup(0) ends code segment start: ; set segment registers: mov ax, data mov ds, ax mov es, ax sub n,1 mov cx,n etq: mov dx,cx mov si,200h ; 现在SI指向tab数组的起始地址 mov bl,0 mov al,[si] bcl: cmp al,[si+1] jbe con ; 交换al和[si+1]的内容 mov dl,al mov al,[si+1] mov [si+1],dl inc bl ; 标记发生了交换 con: inc si mov al,[si] ; 更新AL为当前位置的元素 dec dx jnz bcl cmp bl,0 je fin ; 无交换则提前终止 dec cx jnz etq ; 跳回外层循环开头 fin: mov ax, 4c00h ; exit to operating system. int 21h ends end start ; set entry point and stop the assembler.
内容的提问来源于stack exchange,提问作者Zahra
相关产品推荐
相关产品推荐

