汇编 快排

写在最前面:本文参考  快速排序 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

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值