汇编语言实现快速冒泡排序
DATASSEGMENT
DATADB24,18,8,16,66,56,86,6,10,98
COUNTDB10,10
DATASENDS
CODESSEGMENT
ASSUMECS:CODES,DS:DATAS,ES:DATAS
START:
MOVAX,DATAS
MOVDS,AX
MOVES,AX
MOVBL,1;改进版本,用BL来检验是否排序完成,减少循环次数
LOOP1:
CMPBL,0
JEDATAOUT;ZF1,若相等或为0,则跳转
XORBL,BL;用逻辑异或将BL清零
MOVCL,COUNT;COUNT用于外层的计数
DECCL;CL减一,CL用于内层的计数
PUSHCX;将CX压入堆栈
LEADI,DATA;将数据段首地址赋值给DI
LOOP2:
MOVAL,〔DI〕
CMPAL,〔DI1〕;将前一个数与后一个数比较
JLELOOP3;ZF1或SF!OF若前一个数小于或等于后一个数,则跳转到LOOP3
XCHG〔DI1〕,AL;前者大于后者,则交换两数
MOV〔DI〕,AL;如果前一个数字大于后一个数字,则交换
MOVBL,1
LOOP3:
INCDI;指针加一
LOOPLOOP2;循环L00P2,直到CX0成立
POPCX;将CX从堆栈中弹出
MOVCOUNT,CL;改变外层计数器的值
JMPLOOP1
DATAOUT:
MOVCL,10;开始数据输出
LEADI,DATA;载入数据段(数组)首地址
NEXT:
MOVAX,0;输出下一个数
MOVBH,2;输出的数字之间的空格
MOVAL,〔DI〕;取数
CMPAL,0
JGENON;如果是非负数,则跳至NON
NEGAL;若是负数,将AL中的负数取补转成对应的正数
PUSHAX;INT21H中断将会有一个返回值
MOVAH,2;同时显示负数的标记‘’
MOVDL,;注意这个时候AX的值会因为21H中断的调用而改变,所以先要保存起来
INT21H;若是负数,在屏幕上显示‘’号
POPAX;某些中断之后AX会改变
NON:XORAH,AH;将AH清零
DIVCOUNT1;除以10取十位
MOVDH,AH;AH是余数,AL是商(如果是个位数,则AL为零)
CMPAL,0
JESINGLE;如果AL为零(个位数),则跳转到DIR,直接输出十位数
ADDAL,30H;将数字转换成ASC码
MOVDL,AL;数字放入DL,在屏幕输出
MOVAH,2
INT21H;显示十位上的数值
SINGLE:
MOVAL,DH;将余数(个位数)放入AL
XORAH,AH;将AH清零
ADDAX,3030H
MOVDL,AL;所以最好在显示时判断是否是大于100或者小于100再根据判断结果来处理DIV
OUTP:MOVAH,2;显示输出功能
INT21H;显示个位数
DECBH;BH减一
JZXT;若相等或为0,则跳转
MOVDL,BL;BL为零,屏幕输出空格
JMPOUTP
XT:DECCL;输出数组下一个
JZDONE;如果ZF标志位为零(CL为零),则程序完成
INCDI;数组指针1
JMPNEXT;继续输出数组下一个数
DONE:MOVAH,1;键盘输入并回显功能,目的是使程序输出窗口暂停,以便看到输出结果
INT21H
MOVAH,4CH;带返回码结束功能
INT21H;返回系统
CODESENDS
ENDSTART