写在最前面:本文参考 快速排序 8086汇编
网站地址http://www.cnblogs.com/persistences/archive/2012/11/21/2780194.html
在此基础上,增加了输入和输出功能
DATA SEGMENT
NUM DB '?'
TMP DW 0
BUF DW 200 DUP('?')
SAE DW 4 DUP('?')
MES1 DB 'Input number, the range is 1 to 65534, and divided by blank$'
MES2 DB 'Input error! You must input again$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
BEGIN:
MOV AX, DATA
MOV DS, AX
CALL PRINT_MESSAGE
CALL INPUT
;-------------------
XOR BH, BH ;获得BUF数组的头尾指针
MOV BL, [NUM]
MOV DI, OFFSET BUF
MOV SI, OFFSET BUF
ADD SI, BX
ADD SI, BX
DEC SI
DEC SI
;-------------------
CALL SORT
CALL CRLF
;------------------
XOR CX, CX
MOV CL, [NUM]
MOV DI, OFFSET BUF
SHOW:
MOV BX, [DI]
CALL TRANSLATE ;十六进制转换十进制
CALL PRINT ;打印下一个数据
CALL BLANK ;输出空格
ADD DI, 2 ;对下一个数据进行操作
LOOP SHOW
;------------------
MOV AH, 4CH ;返回DOS
INT 21H
;-----------------------打印提示语句------------------------
PRINT_MESSAGE PROC
MOV DX, OFFSET MES1
MOV AH, 9
INT 21H
CALL CRLF
RET
PRINT_MESSAGE ENDP
;--------------------------------------------------------
;-----------------------输入函数INPUT------------------------
;功能:输入十进制数,并转换为十六进制数
;入口参数:无
;出口参数:BUF存储转换后的十六进制数,NUM存储输入的个数
INPUT PROC
MOV DI, OFFSET BUF
MOV CL, 0 ;CL记录一共输入了多少个数
NKEY:
MOV AX, TMP ;把输入的十进制转化为十六进制
MOV BX, 10 ;从高位到低位输入
MUL BX ;每输入一个低位,高位数要乘10
MOV BX, AX ;把高位寄存到BL
MOV AH, 1 ;输入一个字符
INT 21H
CMP AL, ' ' ;判断输入是否为空格,若是,跳到SAVE
JZ NEXT_ONE
CMP AL, 0DH ;判断输入是否为回车,若是,跳到EXIT
JZ EXIT0
CMP AL, '0' ;输入字符要在0-9内
JB INPUT_ERROR
CMP AL, '9'
JA INPUT_ERROR
SUB AL, 30H
XOR AH, AH
ADD BX, AX ;高位和低位相加
MOV TMP, BX ;把结果存储到TMP
JMP NKEY ;下一个字符
NEXT_ONE:
MOV BX, TMP ;把输入的数存储到BUF中
MOV [DI], BX
ADD DI, 2 ;DI指针指向下一个位置
INC CL ;个数加一
MOV TMP, 0 ;TMP清零
JMP NKEY
EXIT0:
MOV BX, TMP ;把输入的数存储到BUF中
MOV [DI], BX
INC DI ;DI指针指向下一个位置
INC CL ;个数加一
MOV [NUM], CL ;把个数储存到NUM
MOV TMP, 0 ;TMP清零
RET
INPUT_ERROR:
CALL ERROR
RET
INPUT ENDP
;---------------------------------------------------------------------
;-----------------------------排序函数SORT----------------------------
;功能:对输入的数进行排序,AX中存储着KEY的地址
;入口参数:DI,SI存储的头指针和尾指针
;出口参数:BUF中排序好的十六进制数
SORT PROC
PUSH DI ;存储头指针
PUSH SI ;存储尾指针
CMP DI, SI ;若头指针和尾指针相同,排序完成
JNB EXIT1
;-------------- ;把数组进行划分
PUSH DI ;把比KEY小的分一组,比KEY大的分一组
PUSH SI
CALL DISPART
POP SI
POP DI
;--------------
PUSH DI
;-------------- ;对比KEY大的一组进行递归排序
MOV DI, AX ;AX中存储着KEY的地址
ADD DI, 2
PUSH DI
PUSH SI
CALL SORT
POP SI
POP DI
;--------------
POP DI
;-------------- ;对比KEY小的一组进行递归排序
MOV SI, AX ;AX中存储着KEY的地址
DEC SI
DEC SI
PUSH DI
PUSH SI
CALL SORT
POP SI
POP DI
;--------------
EXIT1:
POP SI ;排序完成,退出
POP DI
RET
SORT ENDP
;----------------------------------------------------------------------
;---------------------------划分函数DISPART----------------------------
;功能:划分数组成比KEY大的一组和比KRY小的一组
;入口参数:BUF中存储的十六进制数,DI,SI的头指针和尾指针
;出口参数:划分好大小的数组,以及AX存储着KEY的地址
DISPART PROC
PUSH BX
PUSH DX
MOV CX, [DI] ;取第一个数为KEY
LOOP0:
CMP DI, SI ;头指针大于尾指针相等,划分结束
JNB EXIT2
LOOP1: ;LOOP1是划分比KEY大的数
CMP CX, [SI]
JA SWAP1 ;若[SI]比CX小,把[SI]和CX进行交换
CMP DI, SI ;若DI>SI,划分就结束
JNB LOOP2
DEC SI
DEC SI ;否则,SI指向前一个数据
JMP LOOP1 ;循环
SWAP1:
MOV BX, [SI]
MOV DX, [DI]
MOV [DI], BX
MOV [SI], DX
LOOP2: ;LOOP2是划分比KEY小的数
CMP [DI], CX
JA SWAP2 ;若[DI]比CX大,把[DI]和CX进行交换
CMP DI, SI ;若DI>SI,划分就结束
JNB LOOP0
INC DI
INC DI ;否则,DI指向后一个数据
JMP LOOP2 ;循环
SWAP2:
MOV BX, [SI]
MOV DX, [DI]
MOV [DI], BX
MOV [SI], DX
;--------------
JMP LOOP0 ;完成一次循环,进行下一次,直到划分结束
;--------------
EXIT2:
MOV AX, DI ;AX记录KEY的位置
POP DX
POP BX
RET
DISPART ENDP
;-------------------------------------------------------------------------------------------
;--------------------------------------转换函数TRANSLATE------------------------------------
;功能:把十六进制数转换为十进制数,并把十进制数的每一位存储到SAE中
;入口参数:BUF中的每一个十六进制数
;出口参数:SAE中存储着十进制数的每一位
TRANSLATE PROC
PUSH CX
MOV SI, OFFSET SAE
MOV CX, 10000
CALL DISP
MOV CX, 1000
ADD SI, 2
CALL DISP
MOV CX, 100
ADD SI, 2
CALL DISP
MOV CX, 10
ADD SI, 2 ;SAE记录十进制数的下一位
CALL DISP
MOV CX, 1
ADD SI, 2 ;SAE记录十进制数的下一位
CALL DISP
POP CX
RET
TRANSLATE ENDP
;-------------------------------------------------------------------------------------------
;-------------------------------------转换函数DISP------------------------------------------
;功能:在TRANSLATE的调用下进行进制转换
;入口参数:BX中存储着BUF中的十六进制数
;出口参数:SAE中存储着十进制数的每一位
DISP PROC
PUSH AX
PUSH CX
PUSH DX
MOV AX, BX ;把BX存储的十六进制送到AX做除法
XOR DX, DX
DIV CX
MOV BX, DX ;把余数送到BX
MOV [SI], AX ;把商送到SAE中
POP DX
POP CX
POP AX
RET
DISP ENDP
;-------------------------------------------------------------------------------------------
;--------------------------------------打印函数PRINT----------------------------------------
;功能:把SAE中十进制数的每一位进行打印
;入口参数:SAE中十进制数的每一位
;出口参数:无
PRINT PROC
;-------------------------------- ;这些代码是为了去掉前缀的零
PUSH CX
XOR CX, CX
MOV CL, 6
MOV SI, OFFSET SAE
DEC SI
DEC SI
PREFIX_ZERO:
DEC CL
ADD SI, 2
CMP [SI], 0
JZ PREFIX_ZERO
;---------------------------------
;---------------------------------
WRITE: ;打印十进制的每一位
MOV DL, [SI]
ADD DL, 30H
MOV AH, 2
INT 21H
ADD SI, 2
LOOP WRITE
POP CX
RET
;---------------------------------
PRINT ENDP
;------------------------------------------------------------------------------------
;-------------------------------------错误处理---------------------------------------
ERROR PROC
CALL CRLF
MOV DX, OFFSET MES2
MOV AH, 9
INT 21H
CALL CRLF
CALL CRLF
CALL CRLF
JMP BEGIN
RET
ERROR ENDP
;------------------------------------------------------------------------------------
;-------------------------------------输出换行和回车---------------------------------
CRLF PROC
MOV DL, 0DH
MOV AH, 2
INT 21H
MOV DL, 0AH
MOV AH, 2
INT 21H
RET
CRLF ENDP
;------------------------------------------------------------------------------------
;-------------------------------------输出空格---------------------------------------
BLANK PROC
MOV DL, ' '
MOV AH, 2
INT 21H
RET
BLANK ENDP
;------------------------------------------------------------------------------------
CODE ENDS
END BEGIN