home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
pcmag
/
vol7n17.arc
/
PP717.ARC
/
TRYQSORT.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-08-30
|
12KB
|
274 lines
;----------------------------------------------------------------------
; 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