如何编写可同时处理字节和字数组的子程序?现有代码无法终止
冒泡排序子程序无限循环问题的修复
你的代码存在多个核心问题,导致程序无法终止且无法正确处理字节数组:
- 参数传递错误:调用
bubblesort时,你给字数组data(5个元素)传了cx=10,给字节数组data2(5个元素)传了cx=20——cx应该代表元素个数,而非总字节数。 - 未区分字/字节的寻址逻辑:不管是字还是字节数组,你都用16位寄存器
ax读取元素,处理字节数组时会错误地读取相邻两个字节作为一个值,导致比较逻辑完全混乱。 - 统一步长与循环条件错误:原代码内层循环每次
si+2、用字节偏移量和cx比较,这只适用于字数组;字节数组需要si+1,循环条件也应基于元素个数而非字节数。 - 排序终止逻辑失效:字节数组的比较和交换逻辑全错,
swapflag会被错误地持续置1,导致mainloop无限循环。
修复方案
要让子程序同时支持字和字节数组,需增加一个参数指定元素宽度(用dl:1代表字节,2代表字),并在子程序中根据宽度调整寻址、步长和交换逻辑:
- 修正参数传递:
cx传元素个数,dl传元素宽度 - 调整循环边界计算:根据元素个数和宽度计算内层循环的最大偏移量
- 分支处理字/字节的比较与交换:用8位寄存器处理字节,16位寄存器处理字
- 修正步长:字节数组步长为1,字数组步长为2
修改后的完整代码
[org 0x0100] jmp start data: dw 60,40,50,22,5 ; 5个元素的字数组 data2: db 3,4,1,9,6 ; 5个元素的字节数组 swapflag: db 0 bubblesort: push bx push si push ax push dx dec cx ; 内层循环最多需要比较 (元素数-1) 次 mov ax, cx mul dl ; 计算最大偏移量: (元素数-1)*宽度 mov cx, ax ; cx现在存储最大偏移值 mainloop: mov si, 0 mov byte [swapflag], 0 innerloop: cmp dl, 2 ; 判断是否是字数组 je word_compare byte_compare: ; 字节数组处理逻辑 mov al, [bx+si] cmp al, [bx+si+1] jbe byte_noswap ; 交换字节 xchg al, [bx+si+1] mov [bx+si], al mov byte [swapflag], 1 byte_noswap: add si, 1 ; 字节步长1 jmp check_loop word_compare: ; 字数组处理逻辑 mov ax, [bx+si] cmp ax, [bx+si+2] jbe word_noswap ; 交换字 xchg ax, [bx+si+2] mov [bx+si], ax mov byte [swapflag], 1 word_noswap: add si, 2 ; 字步长2 check_loop: cmp si, cx jne innerloop cmp byte [swapflag], 1 je mainloop pop dx pop ax pop si pop bx ret start: mov bx, data mov cx, 5 ; 元素个数5 mov dl, 2 ; 宽度2(字) call bubblesort mov bx, data2 mov cx, 5 ; 元素个数5 mov dl, 1 ; 宽度1(字节) call bubblesort mov ax, 0x4c00 int 0x21
内容的提问来源于stack exchange,提问作者Haruto
相关产品推荐
相关产品推荐

