home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol7n17.zip / PP717.ZIP / TRYQSORT.ASM < prev    next >
Assembly Source File  |  1988-08-30  |  12KB  |  274 lines

  1. ;----------------------------------------------------------------------
  2. ; TRYQSORT.ASM    Demonstration of MASM Quicksort
  3. ; Copyright (c) 1988 Ziff Communications Co.
  4. ; PC Magazine * Ray Duncan * 12-13-88
  5. ;----------------------------------------------------------------------
  6. true    equ     1
  7. false   equ     0
  8.                         ; the next two equates control the demo type...
  9. singles equ     true    ; set true for integer demo, false for string demo
  10. strings equ     false   ; set true for string demo, false for integer demo
  11.  
  12. stdin   equ     0               ; standard input handle
  13. stdout  equ     1               ; standard output handle
  14. stderr  equ     2               ; standard error handle
  15.  
  16. cr      equ     0dh             ; ASCII carriage return
  17. lf      equ     0ah             ; ASCII line feed
  18.  
  19.         if      strings
  20. itemsiz equ     80              ; bytes per string item
  21.         endif
  22.         if      singles
  23. itemsiz equ     2               ; bytes per integer item
  24.         endif
  25.  
  26. n_items equ     25              ; max items to sort
  27.  
  28. _TEXT   segment word public 'CODE'
  29.         assume  cs:_TEXT,ds:_DATA
  30.         extrn   itoa:near
  31.         extrn   atoi:near
  32.         extrn   qsort:near
  33.  
  34. main    proc    near
  35.  
  36.         mov     ax,_DATA        ; make our data segment
  37.         mov     ds,ax           ; addressable...
  38.         cld                     ; string ops safety first
  39. main1:                          ; begin entry of data
  40.         mov     word ptr ix1,0  ; initialize array index
  41.         push    ds              ; force ES = data segment
  42.         pop     es
  43.  
  44.         mov     di,offset items ; initialize data array
  45.         mov     cx,(n_items*itemsiz)
  46.         xor     al,al
  47.         rep stosb
  48.                                 ; display "Enter xxx to sort"
  49.         mov     dx,offset msg1  ; DS:DX = message address
  50.         mov     cx,msg1_len     ; CX = message length
  51.         mov     bx,stdout       ; BX = handle
  52.         mov     ah,40h          ; Fxn 40H = write
  53.         int     21h             ; transfer to MS-DOS
  54. main2:                          ; convert item number to ASCII string...
  55.         mov     ax,ix1          ; 1-based item number
  56.         inc     ax
  57.         mov     bx,offset msg3a ; address for string
  58.         call    b2dec           ; convert it
  59.                                 ; display item number
  60.         mov     dx,offset msg3  ; DS:DX = message address
  61.         mov     cx,msg3_len     ; CX = length
  62.         mov     bx,stdout       ; BX = handle
  63.         mov     ah,40h          ; Fxn 40H = write
  64.         int     21h             ; transfer to MS-DOS
  65.  
  66.         if      singles         ; if integers version  ---
  67.                                 ; read keyboard entry    |
  68.         mov     dx,offset ibuff ; DS:DX = input buffer   |
  69.         mov     cx,80           ; CX = max input length  |
  70.         mov     bx,stdin        ; BX = handle            |
  71.         mov     ah,3fh          ; Fxn 3FH = read         |
  72.         int     21h             ; transfer to MS-DOS     |
  73.                                 ;                        |
  74.         cmp     ax,2            ; was anything entered?  |
  75.         je      main3           ; empty line, exit       |
  76.                                 ;                        |
  77.         mov     si,offset ibuff ; convert input to       |
  78.         call    atoi            ; binary in reg. AX      |
  79.                                 ;                        |
  80.         mov     bx,ix1          ; put data into array    |
  81.         shl     bx,1            ; (item number * 2)      |
  82.         mov     word ptr [bx+items],ax ;                 |
  83.         endif                   ; ------------------------
  84.  
  85.         if      strings         ; if strings version -----
  86.         mov     ax,ix1          ; calculate array offset |
  87.         mov     dx,itemsiz      ; for entered string     |
  88.         imul    dx              ;                        |
  89.         mov     dx,ax           ;                        |
  90.         add     dx,offset items ; DS:DX = array address  |
  91.         mov     cx,itemsiz      ; CX = max input length  |
  92.         mov     bx,stdin        ; BX = handle            |
  93.         mov     ah,3fh          ; Fxn 3FH = read         |
  94.         int     21h             ; transfer to MS-DOS     |
  95.                                 ;                        |
  96.         cmp     ax,2            ; was anything entered?  |
  97.         je      main3           ; empty line, exit       |
  98.         endif                   ; ------------------------
  99.         
  100.         inc     word ptr ix1    ; count items stored
  101.                                 ; and don't exceed maximum
  102.         cmp     word ptr ix1,n_items
  103.         jne     main2           ; get another entry
  104. main3:                          ; empty line entered...
  105.         cmp     word ptr ix1,0  ; any data in array?
  106.         je      main5           ; no, just exit
  107.                                 ; otherwise sort data...
  108.         mov     si,offset items ; DS:SI = first item
  109.         mov     ax,ix1          ; DS:DI = last item
  110.         dec     ax
  111.         mov     di,itemsiz
  112.         imul    di
  113.         mov     di,ax
  114.         add     di,si
  115.         mov     bx,_TEXT        ; ES:BX = address of
  116.         mov     es,bx           ; compare routine
  117.         if      singles
  118.         mov     bx,offset compi
  119.         endif
  120.         if      strings
  121.         mov     bx,offset comps
  122.         endif
  123.         mov     ax,itemsiz      ; AX = bytes per item
  124.         call    qsort           ; call QuickSort
  125.                                 ; display sorted data...
  126.         mov     word ptr ix2,0  ; initialize array index
  127.                                 ; display "Here are the sorted xxx..."
  128.         mov     dx,offset msg2  ; DS:DX = message address
  129.         mov     cx,msg2_len     ; CX = message length
  130.         mov     bx,stdout       ; BX = handle
  131.         mov     ah,40h          ; Fxn 40H = write
  132.         int     21h             ; transfer to MS-DOS
  133. main4:                          ; display next item...
  134.                                 ; convert item number to ASCII string
  135.         mov     ax,ix2          ; 1-based item number
  136.         inc     ax              
  137.         mov     bx,offset msg3a ; address for string
  138.         call    b2dec           ; convert it
  139.  
  140.                                 ; display item number
  141.         mov     dx,offset msg3  ; DS:DX = message address
  142.         mov     cx,msg3_len     ; CX = message length
  143.         mov     bx,stdout       ; BX = handle
  144.         mov     ah,40h          ; Fxn 40H = write
  145.         int     21h             ; transfer to MS-DOS
  146.  
  147.         if      singles         ; if integers version ---
  148.         mov     bx,ix2          ; calc. array offset    |
  149.         shl     bx,1            ; and get data          |
  150.         mov     ax,word ptr [bx+items] ;                |
  151.                                 ;                       |
  152.                                 ; convert data to ASCII |
  153.         mov     cx,10           ; use base 10           |
  154.         mov     si,offset obuff ; address for string    |
  155.         call    itoa            ; convert it            |
  156.                                 ;                       |
  157.                                 ; display integer       |
  158.         mov     cx,ax           ; CX = string length    |
  159.         mov     dx,si           ; DS:DX = string addr.  |
  160.         mov     bx,stdout       ; BX = handle           |
  161.         mov     ah,40h          ; Fxn 40H = write       |
  162.         int     21h             ; transfer to MS-DOS    |
  163.         endif                   ; -----------------------
  164.  
  165.         if      strings         ; if strings version ----
  166.         mov     ax,ix2          ; calculate array addr. |
  167.         mov     dx,itemsiz      ; DS:DX = array element |
  168.         imul    dx              ;                       |
  169.         mov     dx,ax           ;                       |
  170.         add     dx,offset items ;                       |
  171.         push    ds              ; scan for string end   |
  172.         pop     es              ;                       |
  173.         mov     di,dx           ;                       |
  174.         mov     cx,-1           ;                       |
  175.         xor     al,al           ;                       |       
  176.         repnz scasb             ;                       |       
  177.         not     cx              ; CX = length without   |
  178.         sub     cx,3            ;      CR and LF        |
  179.         mov     bx,stdout       ; BX = handle           |
  180.         mov     ah,40h          ; Fxn 40H = write       |
  181.         int     21h             ; transfer to MS-DOS    |
  182.         endif                   ; -----------------------
  183.  
  184.         inc     word ptr ix2    ; advance through array
  185.         mov     ax,ix2          ; done with array yet?
  186.         cmp     ax,ix1
  187.         jne     main4           ; no, display another
  188.         jmp     main1           ; restart user entry
  189.  
  190. main5:  mov     ax,4c00h        ; final exit to MS-DOS
  191.         int     21h
  192.  
  193. main    endp
  194. '----------------------------------------------------------------------
  195. ; convert binary value 0-99 to decimal ASCII chars.
  196. ; call with AL = binary data, BX = addr. for 2 chars.
  197. ;----------------------------------------------------------------------
  198. b2dec   proc    near
  199.  
  200.         aam                     ; divide AL by 10, leaving
  201.                                 ; AH=quotient, AL=remainder
  202.         add     ax,'00'         ; convert to ASCII
  203.         mov     [bx],ah         ; store ten's digit
  204.         mov     [bx+1],al       ; store one's digit
  205.         ret                     ; return to caller
  206.  
  207. b2dec   endp
  208. ;----------------------------------------------------------------------
  209.         if      singles
  210. compi   proc    far             ; compare two integers
  211.                                 ; call with DS:SI = int 1
  212.         mov     ax,[si]         ;           ES:DI = int 2
  213.         cmp     ax,[di]         ;           CX    = length
  214.         ret                     ; returns result in flags
  215.  
  216. compi   endp
  217.         endif
  218.  
  219.         if      strings
  220. comps   proc    far             ; compare two strings
  221.                                 ; call with DS:SI = string 1
  222.                                 ;           ES:DI = string 2
  223.                                 ;           CX    = length
  224.         push    si              ; save registers
  225.         push    di
  226.         repz cmpsb              ; compare strings
  227.         pop     di              ; restore registers
  228.         pop     si
  229.         ret                     ; returns result in flags
  230.  
  231. comps   endp
  232.         endif
  233.  
  234. _TEXT   ends
  235. ;----------------------------------------------------------------------
  236. _DATA   segment word public 'DATA'
  237.  
  238. msg1    db      cr,lf,lf
  239.         if      singles
  240.         db      'Enter numbers to sort...'
  241.         endif
  242.         if      strings
  243.         db      'Enter strings to sort...'
  244.         endif
  245.         db      cr,lf
  246. msg1_len equ $-msg1
  247.  
  248. msg2    db      cr,lf
  249.         if      singles
  250.         db      'Here are the sorted numbers...'
  251.         endif
  252.         if      strings
  253.         db      'Here are the sorted strings...'
  254.         endif
  255.         db      cr,lf
  256. msg2_len equ $-msg2
  257.  
  258. msg3    db      cr,lf,'Item '
  259. msg3a   db      'xx: '
  260. msg3_len equ $-msg3
  261.  
  262. ibuff   db      80 dup (?)      ; keyboard input buffer
  263. obuff   db      80 dup (?)      ; output conversion buffer
  264. items   db      (n_items * itemsiz) dup (0) ; holds data to sort
  265. ix1     dw      0               ; number of items in array
  266. ix2     dw      0               ; array output pointer
  267.  
  268. _DATA   ends
  269.  
  270. STACK   segment para stack 'STACK'
  271.         db      4096 dup (?)
  272. STACK   ends
  273.         end     main
  274.