home *** CD-ROM | disk | FTP | other *** search
- ;----------------------------------------------------------------------
- ; TRYQSORT.ASM Demonstration of MASM Quicksort
- ; Copyright (c) 1988 Ziff Communications Co.
- ; PC Magazine * Ray Duncan * 12-13-88
- ;----------------------------------------------------------------------
- true equ 1
- false equ 0
- ; the next two equates control the demo type...
- singles equ true ; set true for integer demo, false for string demo
- strings equ false ; set true for string demo, false for integer demo
-
- stdin equ 0 ; standard input handle
- stdout equ 1 ; standard output handle
- stderr equ 2 ; standard error handle
-
- cr equ 0dh ; ASCII carriage return
- lf equ 0ah ; ASCII line feed
-
- if strings
- itemsiz equ 80 ; bytes per string item
- endif
- if singles
- itemsiz equ 2 ; bytes per integer item
- endif
-
- n_items equ 25 ; max items to sort
-
- _TEXT segment word public 'CODE'
- assume cs:_TEXT,ds:_DATA
- extrn itoa:near
- extrn atoi:near
- extrn qsort:near
-
- main proc near
-
- mov ax,_DATA ; make our data segment
- mov ds,ax ; addressable...
- cld ; string ops safety first
- main1: ; begin entry of data
- mov word ptr ix1,0 ; initialize array index
- push ds ; force ES = data segment
- pop es
-
- mov di,offset items ; initialize data array
- mov cx,(n_items*itemsiz)
- xor al,al
- rep stosb
- ; display "Enter xxx to sort"
- mov dx,offset msg1 ; DS:DX = message address
- mov cx,msg1_len ; CX = message length
- mov bx,stdout ; BX = handle
- mov ah,40h ; Fxn 40H = write
- int 21h ; transfer to MS-DOS
- main2: ; convert item number to ASCII string...
- mov ax,ix1 ; 1-based item number
- inc ax
- mov bx,offset msg3a ; address for string
- call b2dec ; convert it
- ; display item number
- mov dx,offset msg3 ; DS:DX = message address
- mov cx,msg3_len ; CX = length
- mov bx,stdout ; BX = handle
- mov ah,40h ; Fxn 40H = write
- int 21h ; transfer to MS-DOS
-
- if singles ; if integers version ---
- ; read keyboard entry |
- mov dx,offset ibuff ; DS:DX = input buffer |
- mov cx,80 ; CX = max input length |
- mov bx,stdin ; BX = handle |
- mov ah,3fh ; Fxn 3FH = read |
- int 21h ; transfer to MS-DOS |
- ; |
- cmp ax,2 ; was anything entered? |
- je main3 ; empty line, exit |
- ; |
- mov si,offset ibuff ; convert input to |
- call atoi ; binary in reg. AX |
- ; |
- mov bx,ix1 ; put data into array |
- shl bx,1 ; (item number * 2) |
- mov word ptr [bx+items],ax ; |
- endif ; ------------------------
-
- if strings ; if strings version -----
- mov ax,ix1 ; calculate array offset |
- mov dx,itemsiz ; for entered string |
- imul dx ; |
- mov dx,ax ; |
- add dx,offset items ; DS:DX = array address |
- mov cx,itemsiz ; CX = max input length |
- mov bx,stdin ; BX = handle |
- mov ah,3fh ; Fxn 3FH = read |
- int 21h ; transfer to MS-DOS |
- ; |
- cmp ax,2 ; was anything entered? |
- je main3 ; empty line, exit |
- endif ; ------------------------
-
- inc word ptr ix1 ; count items stored
- ; and don't exceed maximum
- cmp word ptr ix1,n_items
- jne main2 ; get another entry
- main3: ; empty line entered...
- cmp word ptr ix1,0 ; any data in array?
- je main5 ; no, just exit
- ; otherwise sort data...
- mov si,offset items ; DS:SI = first item
- mov ax,ix1 ; DS:DI = last item
- dec ax
- mov di,itemsiz
- imul di
- mov di,ax
- add di,si
- mov bx,_TEXT ; ES:BX = address of
- mov es,bx ; compare routine
- if singles
- mov bx,offset compi
- endif
- if strings
- mov bx,offset comps
- endif
- mov ax,itemsiz ; AX = bytes per item
- call qsort ; call QuickSort
- ; display sorted data...
- mov word ptr ix2,0 ; initialize array index
- ; display "Here are the sorted xxx..."
- mov dx,offset msg2 ; DS:DX = message address
- mov cx,msg2_len ; CX = message length
- mov bx,stdout ; BX = handle
- mov ah,40h ; Fxn 40H = write
- int 21h ; transfer to MS-DOS
- main4: ; display next item...
- ; convert item number to ASCII string
- mov ax,ix2 ; 1-based item number
- inc ax
- mov bx,offset msg3a ; address for string
- call b2dec ; convert it
-
- ; display item number
- mov dx,offset msg3 ; DS:DX = message address
- mov cx,msg3_len ; CX = message length
- mov bx,stdout ; BX = handle
- mov ah,40h ; Fxn 40H = write
- int 21h ; transfer to MS-DOS
-
- if singles ; if integers version ---
- mov bx,ix2 ; calc. array offset |
- shl bx,1 ; and get data |
- mov ax,word ptr [bx+items] ; |
- ; |
- ; convert data to ASCII |
- mov cx,10 ; use base 10 |
- mov si,offset obuff ; address for string |
- call itoa ; convert it |
- ; |
- ; display integer |
- mov cx,ax ; CX = string length |
- mov dx,si ; DS:DX = string addr. |
- mov bx,stdout ; BX = handle |
- mov ah,40h ; Fxn 40H = write |
- int 21h ; transfer to MS-DOS |
- endif ; -----------------------
-
- if strings ; if strings version ----
- mov ax,ix2 ; calculate array addr. |
- mov dx,itemsiz ; DS:DX = array element |
- imul dx ; |
- mov dx,ax ; |
- add dx,offset items ; |
- push ds ; scan for string end |
- pop es ; |
- mov di,dx ; |
- mov cx,-1 ; |
- xor al,al ; |
- repnz scasb ; |
- not cx ; CX = length without |
- sub cx,3 ; CR and LF |
- mov bx,stdout ; BX = handle |
- mov ah,40h ; Fxn 40H = write |
- int 21h ; transfer to MS-DOS |
- endif ; -----------------------
-
- inc word ptr ix2 ; advance through array
- mov ax,ix2 ; done with array yet?
- cmp ax,ix1
- jne main4 ; no, display another
- jmp main1 ; restart user entry
-
- main5: mov ax,4c00h ; final exit to MS-DOS
- int 21h
-
- main endp
- '----------------------------------------------------------------------
- ; convert binary value 0-99 to decimal ASCII chars.
- ; call with AL = binary data, BX = addr. for 2 chars.
- ;----------------------------------------------------------------------
- b2dec proc near
-
- aam ; divide AL by 10, leaving
- ; AH=quotient, AL=remainder
- add ax,'00' ; convert to ASCII
- mov [bx],ah ; store ten's digit
- mov [bx+1],al ; store one's digit
- ret ; return to caller
-
- b2dec endp
- ;----------------------------------------------------------------------
- if singles
- compi proc far ; compare two integers
- ; call with DS:SI = int 1
- mov ax,[si] ; ES:DI = int 2
- cmp ax,[di] ; CX = length
- ret ; returns result in flags
-
- compi endp
- endif
-
- if strings
- comps proc far ; compare two strings
- ; call with DS:SI = string 1
- ; ES:DI = string 2
- ; CX = length
- push si ; save registers
- push di
- repz cmpsb ; compare strings
- pop di ; restore registers
- pop si
- ret ; returns result in flags
-
- comps endp
- endif
-
- _TEXT ends
- ;----------------------------------------------------------------------
- _DATA segment word public 'DATA'
-
- msg1 db cr,lf,lf
- if singles
- db 'Enter numbers to sort...'
- endif
- if strings
- db 'Enter strings to sort...'
- endif
- db cr,lf
- msg1_len equ $-msg1
-
- msg2 db cr,lf
- if singles
- db 'Here are the sorted numbers...'
- endif
- if strings
- db 'Here are the sorted strings...'
- endif
- db cr,lf
- msg2_len equ $-msg2
-
- msg3 db cr,lf,'Item '
- msg3a db 'xx: '
- msg3_len equ $-msg3
-
- ibuff db 80 dup (?) ; keyboard input buffer
- obuff db 80 dup (?) ; output conversion buffer
- items db (n_items * itemsiz) dup (0) ; holds data to sort
- ix1 dw 0 ; number of items in array
- ix2 dw 0 ; array output pointer
-
- _DATA ends
-
- STACK segment para stack 'STACK'
- db 4096 dup (?)
- STACK ends
- end main
-