The MASM Forum

Miscellaneous => 16 bit DOS Programming => Topic started by: dungeonfinder on October 26, 2013, 01:41:31 PM

Title: sorting programming
Post by: dungeonfinder on October 26, 2013, 01:41:31 PM
Hi,
Im trying to write a program that will ask the user to enter an N number between 2-f. Then accepts N inputs from user and sort them in ascending order. Below is what I have so far, but it is not working. Please help thanks.





DATA SEGMENT
   MSG1 DB "How many integers would you like to enter? (Please enter from 2 to F)", "$"
   N Db (?)
   s db 20 dup (?) ; string to read/sort/print
   
swap db 1 dup (?) ; "swapped" flag
DATA ENDS

CODE SEGMENT

   assume cs:code,ds:code
   org 100h
   

START:
   mov dx, offset MSG1
   mov ah, 9
   int 21h
   
   
   mov ah,1 ; use DOS to read a character
   int 21H
   mov N,al
   
   mov dx, offset N
   mov ah, 9
   int 21h
   
   
   

   ; read 10 characters
   mov bx,offset s ; start of string
   mov cl,N ; number of characters to read
READC:
   mov ah,1 ; use DOS to read a character
   int 21H
   mov [bx],al ; store character in string
   inc bx ; point to next character in string
   dec cx ; decrement characters left to read
   jnz readc ; repeat until all read
   ; bubble sort loop
SORT:
   mov al,0 ; clear 'values swaped' flag
   mov swap,al
   mov bx,offset s ; point to first character
   mov cx,9 ; set count to compare 9 pairs
NEXT2:
   mov al,[bx] ; get character pair into al, ah
   inc bx ; and point to next character
   mov ah,[bx]
   cmp ah,al ; compare the pair
   jnc noswap ; skip the swap if first is <= second

   mov [bx],al ; swap
   dec bx
   mov [bx],ah
   inc bx
   mov al,1 ; set "swapped" flag
   mov swap,al
NOSWAP:
   dec cx ; compare next pair if not done
   jnz next2
   mov al,swap ; do another pass if any swaps
   cmp al,0
   jnz SORT
   ; print results
   mov bx,offset s ; start of string
   mov cl,N ; number of characters to read
PRINTC:
   mov ah,2 ; use DOS to print a character
   mov dl,[bx] ;
   int 21H
   inc bx ; next character in string
   dec cx ; decrement characters to print
   jnz printc ; repeat until all printed
   
STOP:
   mov ax, 4c00h
   int 21h


CODE ENDS
   END START
      
Title: Re: sorting programming
Post by: japheth on October 26, 2013, 06:19:51 PM

Apparently you want to create a program in COM format ( judging from the "org 100h" line )

To successfully create a COM file, you'll need a bit more bureaucracy. Add these lines to your prog:


DGROUP group CODE, DATA
DOSSEG


Also, you'll have to add a so-called class name to - at least - your CODE segment, because masm uses this name to determine if a segment is supposed to be a "code" segment; change line "CODE SEGMENT" to:


CODE SEGMENT "CODE"


There are a few more (minor) errors in your program, but at least it will now start correctly and you can use DEBUG to find them.
Title: Re: sorting programming
Post by: dedndave on October 26, 2013, 10:48:45 PM
Japheth is trying to show you how to "combine" the data segment with the code segment
which is ok - but a bit overcomplicated

one of the rules for the old "tiny" .COM model is that all the code and data must be in the same segment or group that is less than (64 kb - 256) - the PSP uses 256 bytes

a much simpler method is to use a single segment
        .MODEL  Tiny
        .386
        OPTION  CaseMap:None

;####################################################################################

        .CODE

;************************************************************************************

        ORG     100h

_main   PROC    NEAR

        mov     dx,offset s$Msg
        mov     ah,9
        int     21h

        mov     ax,4C00h
        int     21h

_main   ENDP

;####################################################################################

s$Msg   db 'Hello World !',0Dh,0Ah,24h

;####################################################################################

        END     _main


to build it, you need to use a 16-bit linker
ml /c /omf /AT MyFile.asm
link16 /TINY MyFile.obj,MyFile.exe;
Title: Re: sorting programming
Post by: FORTRANS on October 26, 2013, 11:50:35 PM
Oops, bad idea, sorry.
Title: Re: sorting programming
Post by: MichaelW on October 27, 2013, 02:46:38 AM
Quote from: dedndave on October 26, 2013, 10:48:45 PM
Japheth is trying to show you how to "combine" the data segment with the code segment
which is ok - but a bit overcomplicated

Unless this is a school assignment and full segment definitions are required. Otherwise make it as simple as possible.

.model tiny
.386
.code
.startup
; entry point here
.exit
; data can go here
end


Title: Re: sorting programming
Post by: Gunther on October 27, 2013, 06:21:34 AM
Hi dungeonfinder,

Michael is right and it's a good proposal. And welcome to the forum.

Gunther
Title: Re: sorting programming
Post by: japheth on October 27, 2013, 01:52:32 PM
Quote from: MichaelW on October 27, 2013, 02:46:38 AM
Unless this is a school assignment and full segment definitions are required. Otherwise make it as simple as possible.

Or, he/she might use an old version of Masm - or Tasm ( which was my consideration, because Masm doesn't understand the "(?)" syntax  ).
Title: Re: sorting programming
Post by: Gunther on October 27, 2013, 08:32:35 PM
Quote from: japheth on October 27, 2013, 01:52:32 PM
Or, he/she might use an old version of Masm - or Tasm ( which was my consideration, because Masm doesn't understand the "(?)" syntax  ).

Yes. I think that TASM 5 can be downloaded for free since a few years.

Gunther
Title: Re: sorting programming
Post by: georg on October 30, 2013, 01:29:36 PM
Quote from: dungeonfinder on October 26, 2013, 01:41:31 PM


DATA SEGMENT
   MSG1 DB "How many integers would you like to enter? (Please enter from 2 to F)", "$"
   N Db (?)
   s db 20 dup (?) ; string to read/sort/print
   
swap db 1 dup (?) ; "swapped" flag
DATA ENDS

CODE SEGMENT

   assume cs:code,ds:code
   org 100h
   

START:
   mov dx, offset MSG1
   mov ah, 9
   int 21h
   
   
   mov ah,1 ; use DOS to read a character
   int 21H
   mov N,al
   
   mov dx, offset N
   mov ah, 9
   int 21h
   
   
   

   ; read 10 characters
   mov bx,offset s ; start of string
   mov cl,N ; number of characters to read
READC:
   mov ah,1 ; use DOS to read a character
   int 21H
   mov [bx],al ; store character in string
   inc bx ; point to next character in string
   dec cx ; decrement characters left to read
   jnz readc ; repeat until all read
   ; bubble sort loop
SORT:
   mov al,0 ; clear 'values swaped' flag
   mov swap,al
   mov bx,offset s ; point to first character
   mov cx,9 ; set count to compare 9 pairs
NEXT2:
   mov al,[bx] ; get character pair into al, ah
   inc bx ; and point to next character
   mov ah,[bx]
   cmp ah,al ; compare the pair
   jnc noswap ; skip the swap if first is <= second

   mov [bx],al ; swap
   dec bx
   mov [bx],ah
   inc bx
   mov al,1 ; set "swapped" flag
   mov swap,al
NOSWAP:
   dec cx ; compare next pair if not done
   jnz next2
   mov al,swap ; do another pass if any swaps
   cmp al,0
   jnz SORT
   ; print results
   mov bx,offset s ; start of string
   mov cl,N ; number of characters to read
PRINTC:
   mov ah,2 ; use DOS to print a character
   mov dl,[bx] ;
   int 21H
   inc bx ; next character in string
   dec cx ; decrement characters to print
   jnz printc ; repeat until all printed
   
STOP:
   mov ax, 4c00h
   int 21h


CODE ENDS
   END START
      

such a pleasure to read your program, I like your technique.
Title: Re: sorting programming
Post by: dedndave on October 30, 2013, 02:21:20 PM
in this thread, i describe a bubble sort
it's 16-bit code - and works on byte arrays....

http://www.masmforum.com/board/index.php?topic=12740 (http://www.masmforum.com/board/index.php?topic=12740)
Title: Re: sorting programming
Post by: georg on November 03, 2013, 09:49:15 PM
;--------------------------------------------------------------------------------------------

BSort   PROC   NEAR
;
;Byte Array Bubble Sort
;
;Call With: SI = address of array
;           CX = size of array in bytes
;
;  Returns: the array is sorted, lower values at lower addresses
;
;           all general registers are used and not saved
;
;-------------------------------------------

        jcxz    BSort4            ;if array size = 0, sort is done

        dec     cx                ;count to last byte
        jz      BSort4            ;if array size = 1, sort is done

        mov     bp,1              ;bp = 1 - used to set the swap flag
        xor     dx,dx             ;dx = 0 - initial swap flag
        cmp     cx,bp             ;if cx = 1, there are only 2 bytes
        ja      BSort0            ;more than 2 - skip the adjustment

        mov     bp,dx             ;if only 2 bytes, we want one pass, so flag = 0

BSort0: add     cx,si             ;cx = top address
        dec     si                ;adjust for the skip (DI gets ADD'ed before 1st pass)
        mov     di,-1             ;di = 1 for up, -1 for down (gets NEG'ed before 1st pass)
        mov     bx,si             ;bx = bottom address (gets XCHG'ed with CX before 1st pass)
        dec     bx                ;adjust for "one less" (DI gets SUB'ed before 1st pass)

BSort1: sub     bx,di             ;one less next time
        xchg    bx,cx             ;swap ends
        neg     di                ;switch direction
        add     si,di             ;skip one - already did that pair
        add     si,di             ;skip another one - one less next time

BSort2: mov     ax,[si]           ;get 2 bytes
        cmp     al,ah             ;do they need to be swapped ?
        jbe     BSort3            ;no - next address

        xchg    al,ah             ;yes - swap them
        mov     dx,bp             ;set the swap flag
        mov     [si],ax           ;store the swapped byte pair

BSort3: add     si,di             ;step in the current direction
        cmp     si,bx             ;are we at the end ?
        jnz     BSort2            ;no - next pair

        dec     dx                ;yes - clear the sort flag if it is 1
        jz      BSort1            ;if the sort flag was 1 before DEC, we are not done

BSort4: ret                       ;exit the routine

BSort   ENDP

;--------------------------------------------------------------------------------------------

Such a great code Dave, and is faster.
Title: Re: sorting programming
Post by: dedndave on November 04, 2013, 01:03:23 AM
you could eliminate the use of JCXZ, which is a slow instruction
        or      cx,cx
        jz      BSort4            ;if array size = 0, sort is done

        dec     cx                ;count to last byte
        jz      BSort4            ;if array size = 1, sort is done

Title: Re: sorting programming
Post by: Gunther on November 04, 2013, 01:06:18 AM
Dave,

Quote from: dedndave on November 04, 2013, 01:03:23 AM
you could eliminate the use of JCXZ, which is a slow instruction
        or      cx,cx
        jz      BSort4            ;if array size = 0, sort is done

        dec     cx                ;count to last byte
        jz      BSort4            ;if array size = 1, sort is done



good proposal, but I think JCXZ isn't very critical in that case, because it's not inside the loop.

Gunther
Title: Re: sorting programming
Post by: dedndave on November 04, 2013, 01:13:52 AM
probably right
but, i get chastised if i use JCXZ, LOOP, LODSB, STOSB, or XLAT   :P
Title: Re: sorting programming
Post by: jj2007 on November 04, 2013, 04:43:35 AM
Quote from: dedndave on November 04, 2013, 01:13:52 AM
i get chastised if i use JCXZ
... and rightly so, at least in this case!
        or      cx,cx
        jz      BSort4
        dec     cx                ;count to last byte
        jzjle      BSort4            ;if array size = 1, sort is done
Title: Re: sorting programming
Post by: dedndave on November 04, 2013, 05:27:02 AM
oops - what if the array is 65535 bytes ?   :biggrin:
or 32769 to 65535, for that matter

JBE would work if DEC set the carry flag

probably the best code would be...
        sub     cx,1
        jbe     BSort4
Title: Re: sorting programming
Post by: Gunther on November 04, 2013, 07:04:54 AM
Dave,

Quote from: dedndave on November 04, 2013, 05:27:02 AM
JBE would work if DEC set the carry flag

that won't work. Here's the explanation. (http://stackoverflow.com/questions/13435142/why-the-inc-and-dec-instructions-do-not-affect-the-carry-flag)

Gunther
Title: Re: sorting programming
Post by: dedndave on November 04, 2013, 07:41:17 AM
right - that's why i suggested SUB CX,1
Title: Re: sorting programming
Post by: Gunther on November 04, 2013, 08:49:44 AM
Dave,

Quote from: dedndave on November 04, 2013, 07:41:17 AM
right - that's why i suggested SUB CX,1

So we are on the safe side.

Gunther
Title: Re: sorting programming
Post by: jj2007 on November 04, 2013, 09:34:02 AM
Quote from: dedndave on November 04, 2013, 05:27:02 AM
oops - what if the array is 65535 bytes ?   :biggrin:
or 32769 to 65535, for that matter

Quote from: dungeonfinder on October 26, 2013, 01:41:31 PM
   MSG1 DB "How many integers would you like to enter? (Please enter from 2 to F)", "$"

0fh aka 15 is way below 32769...
Title: Re: sorting programming
Post by: dedndave on November 04, 2013, 10:13:11 AM
ok - but the routine was intended to be more generic   :P
you probably knew that - lol
Title: Re: sorting programming
Post by: jj2007 on November 04, 2013, 11:03:09 AM
Quote from: dedndave on November 04, 2013, 10:13:11 AM
you probably knew that - lol

I would never expect an array with more than 32768 members if total memory was only 640k ;-)
Title: Re: sorting programming
Post by: dedndave on November 04, 2013, 11:06:35 AM
you're kidding, right ?
i used arrays larger than 64 kb sometimes