开始之前
首先这篇文章也算是我学习的一个新的开始吧,算是给自己一个警醒。这次简单分享一下我学习8086指令系统编写冒泡排序的一点心得。我只算一个学习者,其实有些地方我也不是很透彻。
代码分析
1.开头
DATA SEGMENT
BUF DB 50,0,50 DUP(0)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
这些都比较常规了,先定义一个数据段,因为要用DOS的0AH号功能来实现,而该功能要求用户指定一个输入缓冲区来存放输入的字符串。缓冲区一般定义在数据段。第一个字节为用户定义的缓冲区长度,第二个字节为实际输入的字符数(不包括回车),由0AH号功能自动填入,DOS从第三个字节开始存放输入的字符。
然后就是常规的ASSUME指令,给段分配段寄存器的地址。
2.输入字符
LEA DX,BUF
MOV AH,0AH
INT 21H
MOV AH,2
MOV DL,0AH ;空格回车
INT 21H
MOV DL,0DH
INT 21H
取定义的BUF的偏移地址,用DOS的0AH功能(键盘字符串输入),然后接回车和换行的操作使界面更美观,(回车和换行的ASCII码为0DH,0AH)。其次,因为输入的是字符串,由于我个人水平的原因,题目的要求是输入10个十六进制的数用冒泡排序法进行从小到大排序,在这个程序里,需要用空格来分隔字符。
3.循环排序
MOV CX,10
CTT: PUSH CX;冒泡排序需要嵌套循环所以需要入栈和出栈操作
MOV CX,9
LEA SI,BUF
ADD SI,2
LPP: MOV AL,[SI]
CMP AL,[SI+3]
JL CHA
JE CHA2
JMP OUN
CHA:MOV BL,[SI]
MOV AL,[SI+3]
MOV [SI],AL
MOV [SI+3],BL
MOV BL,[SI+1]
MOV AL,[SI+4]
MOV [SI+1],AL
MOV [SI+4],BL
JMP OUN
CHA2:MOV AL,[SI+1]
CMP AL,[SI+4]
JL CHA
JMP OUN
OUN: ADD SI,3
LOOP LPP
POP CX
LOOP CTT
这里因为要用冒泡排序法,其内容是相邻两个数比较大小,按所需要求转换位置,直到不需要转换位置即可。
所以需要嵌套循环,而8086系统的循环应该是只有CX,所以需要进栈和储栈来保护CX的值,用来进行双重循环。
交换位置时我先比较第一位和第三位,跳过空格,如果第一位小于第三位就交换1,3和2,4位,若等于再比较第二位和第四位
再交换,实际上用XCHG交换指令也可以。
4.输出显示
LEA DX,BUF
XOR CH,CH
MOV CL,BUF+1
ADD DX,CX
MOV BX,DX
MOV BYTE PTR[BX+2],'$'
LEA DX,BUF
ADD DX,2
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
最后再用9号DOS功能输出(需要字符串的最后一位必须为$,所以要再最后插入$),结束程序。