News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

sorting programming

Started by dungeonfinder, October 26, 2013, 01:41:31 PM

Previous topic - Next topic

dungeonfinder

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
      

japheth


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.

dedndave

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;

FORTRANS


MichaelW

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


Well Microsoft, here's another nice mess you've gotten us into.

Gunther

Hi dungeonfinder,

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

Gunther
You have to know the facts before you can distort them.

japheth

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  ).

Gunther

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
You have to know the facts before you can distort them.

georg

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.

dedndave

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

georg

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

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.

dedndave

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


Gunther

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
You have to know the facts before you can distort them.

dedndave

probably right
but, i get chastised if i use JCXZ, LOOP, LODSB, STOSB, or XLAT   :P

jj2007

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