The MASM Forum

Miscellaneous => Irvine Book Questions. => Topic started by: MASMClass on May 11, 2014, 08:05:57 AM

Title: Help with Bubble Sorting in MASM
Post by: MASMClass on May 11, 2014, 08:05:57 AM
My classmates and I are working on a MASM project, and we have most of it down, but we need help with sorting methods. I've spent more than a few nights trying to work on this and have come up short. I am brand new to this forum, and I just don;t know who else to ask.
The assignment it to make a student report type of program. It stores first name, last name, ID number, and grade. There are also 7 procedures we need to have, such as create student, modify student, sort students by last name, first name and ID. I can make students and display their information, but I cannot sort them.
Any help is fantastic!


Ill post all of the code here. The methods that need work are SortByLastName and SortByFirstName. I think simply figuring out one will do.

INCLUDE Irvine32.inc
.data
;-----------------------------------------------------------------------------------------------------------
; Messages shown in Main Menu
;-----------------------------------------------------------------------------------------------------------

mainmenu BYTE "Student Record Database",0dh,0ah
BYTE "+-----------------------------------------------------------------------------+",0dh,0ah
BYTE "1. Create Student Record",0dh,0ah
BYTE "2. Update Student Record",0dh,0ah
BYTE "3. Find and Display Student Record",0dh,0ah
BYTE "4. Delete Student Record",0dh,0ah
BYTE "5. Sort Records Using Last Name",0dh,0ah
BYTE "6. Sort Records Using Score",0dh,0ah
BYTE "7. Display All Records",0dh,0ah
BYTE "8. Exit",0dh,0ah
BYTE "+-----------------------------------------------------------------------------+",0dh,0ah,0
prread1 BYTE "Enter a number corresponding to the task you wish to perform: ",0
errpro1 BYTE "Bad input read!  Please enter a valid number: ",0

;-----------------------------------------------------------------------------------------------------------
; Messages shown in Create Student Record
;-----------------------------------------------------------------------------------------------------------

maxmsg BYTE "The number of students is at maximum capacity.",0dh,0ah
BYTE "Please delete a student record if you wish to add a different student.",0dh,0ah,0
creaprt BYTE "Create Student Record",0dh,0ah
BYTE "+-----------------------------------------------------------------------------+",0dh,0ah,0
creapr1 BYTE "Enter Last Name of Student: ",0
creapr2 BYTE "Enter First Name of Student: ",0
creapr3 BYTE "Enter Student ID Number: ",0
creapr4 BYTE "Enter Weighted Average Score: ",0
creapr5 BYTE "The following was entered: ",0
creapr6 BYTE "Is this correct?  Enter 'y' for 'yes,' enter 'n' for 'no.'",0
creapr7 BYTE "Would you like to enter another record?  Enter 'y' for yes, 'n' for no: ",0
errpro2 BYTE "Bad input read! Please enter 'y' or 'n': ",0
nameerr BYTE "Error!  Name entered must only be letters!",0dh,0ah,0
stuiderr BYTE "Error!  Enter an ID in the range of 0-255: ",0
scoreerr BYTE "Error!  Enter a score in the range of 0-100: ",0
;-----------------------------------------------------------------------------------------------------------
; Messages shown in Find and Display Student Record
;-----------------------------------------------------------------------------------------------------------

findtitle BYTE "Find and Display Student Record",0dh,0ah,0
findbuff BYTE "+-----------------------------------------------------------------------------+",0dh,0ah,0
findpro BYTE "Enter the student ID of the record you wish to display: ",0
finderr BYTE "Non-numerical character detected!  Please enter a valid student ID number: ",0
noresult BYTE "No student record found with the ID entered.",0dh,0ah,0

;-----------------------------------------------------------------------------------------------------------
; Messages shown in Sort Student Record by Score
;-----------------------------------------------------------------------------------------------------------

sctitle BYTE "Student Records Sorted by Score",0dh,0ah,


;-----------------------------------------------------------------------------------------------------------
; Messages shown in Display All Records
;-----------------------------------------------------------------------------------------------------------

allprot BYTE "All Student Records",0
buffpr BYTE "+------------------+-------------------+-------------------+------------------+",0
sidebf BYTE "|",0
lnamepr BYTE "Last Name",0
fnamepr BYTE "First Name",0
stuidpr BYTE "Student ID",0
avgscpr BYTE "Average Score",0

;-----------------------------------------------------------------------------------------------------------
; Student Information Parameters and Arrays
;-----------------------------------------------------------------------------------------------------------

stucount DWORD 0 ; counts the number of students entered into database
nameoff DWORD 0 ; offsets each name, dependent on name length
MAXNUMST = 4 ; maximum number of students that can be entered into database
NAMELEN = 10 ; maximum length of student name (10) plus null character
lastname BYTE NAMELEN DUP(0)
firstname BYTE NAMELEN DUP(0)
studentid DWORD 0
averscore DWORD 0
lnamearr BYTE MAXNUMST*NAMELEN DUP(0) ; last name array
fnamearr BYTE MAXNUMST*NAMELEN DUP(0) ; first name array
stuidnum DWORD MAXNUMST DUP(0) ; student id array
avgscore DWORD MAXNUMST DUP(0) ; average score array


.code

main PROC
mov ebx,0
L: call Clrscr

call DisplayMainMenu
call ReadMenuTask
call DumpRegs

T1: cmp eax,1
jne T2
call CreateRecord
jmp L
T2: cmp eax,2
jne T3
call UpdateRecord
jmp L
T3: cmp eax,3
jne T4
call FindDisplayRecord
jmp L
T4:  cmp eax,4
jne T5
call DeleteRecord
jmp L
T5: cmp eax,5
jne T6
call SortByLastName
jmp L
T6: cmp eax,6
jne T7
call SortByScore
jmp L
T7: cmp eax,7
jne T8
call DisplayAllRecords
jmp L
T8: cmp eax,8
je EX

EX: exit

main ENDP


DisplayMainMenu PROC USES edx

mov edx,OFFSET mainmenu
call WriteString
call Crlf
mov edx,OFFSET prread1
call WriteString

ret
DisplayMainMenu ENDP

ReadMenuTask PROC USES edx

L: call ReadDec
cmp eax,9
jb S1
call Crlf
mov edx,OFFSET errpro1
call WriteString
jmp L
S1: cmp eax,0
ja S2
call Crlf
mov edx,OFFSET errpro1
call WriteString
jmp L
S2: ret
ReadMenuTask ENDP

CreateRecord PROC USES ecx edx esi

mov esi,stucount
T1: cmp esi,MAXNUMST
jne T2
call Clrscr
mov edx,OFFSET maxmsg ; Student count at maximum capacity, need to delete
call WriteString ; records to add more

call Crlf
call WaitMsg
jmp EX

T2: call Clrscr

mov edx,OFFSET creaprt
call WriteString

L1: call Crlf
mov edx,OFFSET creapr1 ; Enter Last Name of Student:
call WriteString
mov edx,OFFSET lastname
mov ecx,NAMELEN
call ReadString
call LastNameCheck
cmp eax,0 ; EAX = 0: not all characters were letters
jne L2
call Crlf
mov edx,OFFSET nameerr
call WriteString
jmp L1

L2: call Crlf
mov edx,OFFSET creapr2 ; Enter First Name of Student:
call WriteString
mov edx,OFFSET firstname
mov ecx,NAMELEN
call ReadString
call FirstNameCheck
cmp eax,0 ; EAX = 0: not all characters were letters
jne L3
call Crlf
mov edx,OFFSET nameerr
call WriteString
jmp L2

L3: call Crlf
mov edx,OFFSET creapr3 ; Enter Student ID Number:
call WriteString
L4: call ReadInt
cmp eax,0
jb EI
cmp eax,255
ja EI
mov stuidnum[esi*TYPE stuidnum],eax
call Crlf
jmp L5

EI: mov edx,OFFSET stuiderr
call WriteString
jmp L4

L5: mov edx,OFFSET creapr4 ; Enter Weighted Average Score:
call WriteString
L6: call ReadInt
cmp eax,0
jb EC
cmp eax,100
ja EC
mov avgscore[esi*TYPE avgscore],eax
call Crlf
jmp L7

EC: mov edx,OFFSET scoreerr
call WriteString
jmp L6

L7: mov edx,OFFSET creapr5 ; The following was entered:
call WriteString
call Crlf
call Crlf
mov edx,OFFSET lastname
call WriteString ; Prints last name
call Crlf
mov edx,OFFSET firstname
call WriteString ; Prints first name
call Crlf
mov eax,stuidnum[esi*TYPE stuidnum]
call WriteDec ; Prints student ID
call Crlf
mov eax,avgscore[esi*TYPE avgscore]
call WriteDec ; Prints average score
call Crlf
call Crlf

mov edx,OFFSET creapr6
call WriteString ; Is this correct?  Enter 'y' for yes, enter 'n' for no:
S1: call ReadChar
call Crlf
call Crlf
cmp al,'n'
je T1
cmp al,'y'
je S2
mov edx,OFFSET errpro2
call WriteString
jmp S1

S2: call WriteToArrays
inc esi
inc stucount
add nameoff,NAMELEN

S3: mov edx,OFFSET creapr7 ; Would you like to enter another record?  Enter 'y' for yes, 'n' for no:
call WriteString
call ReadChar
cmp al, 'n'
je EX
cmp al, 'y'
je T1
mov edx,OFFSET errpro2
call WriteString
jmp S3

EX: ret
CreateRecord ENDP

WriteToArrays PROC USES ecx esi

mov esi,0
mov ecx,NAMELEN
L1: mov al,lastname[esi]
add lnamearr[ebx],al
mov al,firstname[esi]
add fnamearr[ebx],al
inc esi
inc ebx
loop L1

ret
WriteToArrays ENDP

LastNameCheck PROC USES ecx edx esi

mov eax,1 ; EAX is true
and lastname[0],0DFh ; Makes first character uppercase
mov esi,0
mov ecx, LENGTHOF lastname

L1: cmp lastname[esi],0
je EX
cmp esi,0 ; Checks to see if the first character in name
jne SK ; Skips if not
cmp lastname[0],41h
jb ER
cmp lastname[0],5Ah
ja ER
jmp L2

SK: or lastname[esi],20h ; Makes every character after the first lowercase
cmp lastname[esi],61h
jb ER ; Error if less than ASCII value for 'a'
cmp lastname[esi],7Ah
ja ER ; Error if greater than ASCII value for 'z'
jmp L2

ER: mov eax,0 ; EAX is false, character is not a letter
jmp EX

L2: inc esi
loop L1

EX: ret
LastNameCheck ENDP

FirstNameCheck PROC USES ecx edx esi

mov eax,1 ; EAX is true
and firstname[0],0DFh ; Makes first character uppercase
mov esi,0
mov ecx, LENGTHOF firstname

L1: cmp firstname[esi],0
je EX
cmp esi,0 ; Checks to see if the first character in name
jne SK ; Skips if not
cmp firstname[0],41h
jb ER
cmp firstname[0],5Ah
ja ER
jmp L2

SK: or firstname[esi],20h ; Makes every character after the first lowercase
cmp firstname[esi],61h
jb ER ; Error if less than ASCII value for 'a'
cmp firstname[esi],7Ah
ja ER ; Error if greater than ASCII value for 'z'
jmp L2

ER: mov eax,0 ; EAX is false, character is not a letter
jmp EX

L2: inc esi
loop L1

EX: ret
FirstNameCheck ENDP

SortByLastName PROC
call Clrscr


mov ecx, NAMELEN
mov edx, LENGTHOF lnamearr
bs_o:
xor ebp,ebp
bs_i:
mov eax, DWORD PTR [edx+ebp*4+4]
cmp DWORD PTR [edx+ebp*4],eax
jb S1
xchg eax, DWORD PTR [edx+ebp*4]
mov DWORD PTR [edx+ebp*4+4], eax
S1:
add ebp,1
cmp ebp,ecx
jb bs_i
loop bs_o
pop ebp

call WriteHeader

call WaitMsg
ret
SortByLastName ENDP

SortByScore PROC USES ecx edx esi
call Clrscr

mov edx,OFFSET sctitle
call WriteString

call WriteHeader

COMMENT @
mov esi,1
mov ecx,stucount
L1: mov eax,avgscore[esi]
cmp eax,avgscore[esi-1]
jbe L2
@

call WaitMsg
ret
SortByScore ENDP

DisplayAllRecords PROC USES eax ebx ecx edx esi
call Clrscr

mov edx,OFFSET allprot
call WriteString
call Crlf
call Crlf

call WriteHeader

call WriteTable

call Crlf
call Crlf
call WaitMsg ; Temporary wait message
ret
DisplayAllRecords ENDP


WriteHeader PROC USES edx
mov dh,2
mov dl,0
call Gotoxy
mov edx,OFFSET buffpr ; Writes horizontal line across the screen
call WriteString
call Crlf

mov edx,OFFSET sidebf ; Writes a vertical boundary
call WriteString

mov edx,OFFSET lnamepr ; Writes "Last Name"
call WriteString

mov dh,3
mov dl,19
call Gotoxy
mov edx,OFFSET sidebf ; Writes boundary between "Last Name" & "First Name"
call WriteString

mov edx,OFFSET fnamepr ; Writes "First Name"
call WriteString

mov dh,3
mov dl,39
call Gotoxy
mov edx,OFFSET sidebf ; Writes boundary between "First Name" & "Student ID"
call WriteString

mov edx,OFFSET stuidpr ; Writes "Student ID"
call WriteString

mov dh,3
mov dl,59
call Gotoxy
mov edx,OFFSET sidebf
call WriteString

mov edx,OFFSET avgscpr ; Writes "Average Score"
call WriteString

mov dh,3
mov dl,78
call Gotoxy
mov edx,OFFSET sidebf
call WriteString
call Crlf

mov edx,OFFSET buffpr
call WriteString
call Crlf
ret
WriteHeader ENDP

WriteTable PROC USES eax ecx edx esi

mov esi,0
mov ecx,NAMELEN
mov dh,5
L1: mov dl,0
call Gotoxy
LI: mov al,lnamearr[esi]
cmp al,0
je LO
call WriteChar
inc esi
loop LI

LO: inc esi
cmp esi,LENGTHOF lnamearr
je S1
cmp lnamearr[esi],0
je LO
mov ecx,NAMELEN
inc dh
jmp L1

S1:
mov esi,0
mov ecx,NAMELEN
mov dh,5
F1: mov dl,20
call Gotoxy
FI: mov al,fnamearr[esi]
cmp al,0
je FO
call WriteChar
inc esi
loop FI

S2:  call Crlf

FO: inc esi
cmp esi,LENGTHOF fnamearr
je S3
cmp fnamearr[esi],0
je FO
mov ecx,NAMELEN
inc dh
jmp F1
S3:
mov esi,0
mov ecx,stucount
mov dh,5
N1: mov dl,40
call Gotoxy
mov eax,stuidnum[esi*TYPE stuidnum]
call WriteDec
mov dl,60
call Gotoxy
mov eax,avgscore[esi*TYPE avgscore]
call WriteDec
inc esi
add dh,2
loop N1
ret
WriteTable ENDP
END main

Let me know if you need any more information. I've cut most of the PROC out so I can post into this forum.

Thank you in advance!

Added code tags
Title: Re: Help with Bubble Sorting in MASM
Post by: jj2007 on May 11, 2014, 08:56:18 AM
    mov ecx, NAMELEN
    mov edx, LENGTHOF lnamearr
bs_o:
    xor ebp,ebp
bs_i:
    mov eax, DWORD PTR [edx+ebp*4+4]


That won't fly. Not surprisingly, it crashes with an access violation.

Could you please re-post this procedure with a decent level of comments?
Title: Re: Help with Bubble Sorting in MASM
Post by: MASMClass on May 11, 2014, 10:15:17 AM
Quote from: jj2007 on May 11, 2014, 08:56:18 AM
   
Could you please re-post this procedure with a decent level of comments?

Sure

SortByLastName PROC
call Clrscr

   
   mov ecx, NAMELEN                          ;length of the maximum characters per name in array
   mov edx, LENGTHOF lnamearr         ; the total length of the last name array
bs_o:
   xor ebp,ebp                                     
bs_i:
   mov eax, DWORD PTR [edx+ebp*4+4]   ; trying to give eax the value of the first name
   cmp DWORD PTR [edx+ebp*4],eax         ; comparing the second last name to the first last name
   jb S1                                                        ; if already in alphabetical order, skip
   xchg eax, DWORD PTR [edx+ebp*4]       ; if not in order then exchange them
   mov DWORD PTR [edx+ebp*4+4], eax    ; move eax to the next position for comparison
S1:
   add ebp,1                                                ; increment ebp
   cmp ebp,ecx                                             ; compares ebp to ecx
   jb bs_i                                                      ; repeat if not complete
   loop bs_o
   pop ebp

   call WriteHeader                                      ; writes the names to the menu

   call WaitMsg                                              ;"press any key to continue"
   ret                                                            ; return values to previous conditions
SortByLastName   ENDP
Title: Re: Help with Bubble Sorting in MASM
Post by: hutch-- on May 11, 2014, 02:17:26 PM
Don't be afraid to have a look at the MASM32 example code "bubble.asm" in the "exampl06\bubble" directory.
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 11, 2014, 07:06:19 PM
Quote from: MASMClass on May 11, 2014, 10:15:17 AM
Quote from: jj2007 on May 11, 2014, 08:56:18 AM
   
Could you please re-post this procedure with a decent level of comments?

Sure

SortByLastName PROC
call Clrscr

   
   mov ecx, NAMELEN                          ;length of the maximum characters per name in array
   mov edx, LENGTHOF lnamearr         ; the total length of the last name array
bs_o:
   xor ebp,ebp                                     
bs_i:
   mov eax, DWORD PTR [edx+ebp*4+4]   ; trying to give eax the value of the first name
   cmp DWORD PTR [edx+ebp*4],eax         ; comparing the second last name to the first last name
   jb S1                                                        ; if already in alphabetical order, skip
   xchg eax, DWORD PTR [edx+ebp*4]       ; if not in order then exchange them
   mov DWORD PTR [edx+ebp*4+4], eax    ; move eax to the next position for comparison
S1:
   add ebp,1                                                ; increment ebp
   cmp ebp,ecx                                             ; compares ebp to ecx
   jb bs_i                                                      ; repeat if not complete
   loop bs_o
   pop ebp

   call WriteHeader                                      ; writes the names to the menu

   call WaitMsg                                              ;"press any key to continue"
   ret                                                            ; return values to previous conditions
SortByLastName   ENDP
Hi
Quote
SortByLastName PROC
call Clrscr

   
    mov ecx, NAMELEN                          ;length of the maximum characters per name in array
    mov edx, LENGTHOF lnamearr         ; the total length of the last name array
bs_o:
    xor ebp,ebp                                     
bs_i:
    mov eax, DWORD PTR [edx+ebp*4+4]   ; trying to give eax the value of the first name
    cmp DWORD PTR [edx+ebp*4],eax         ; comparing the second last name to the first last name
    jb S1                                                        ; if already in alphabetical order, skip
    xchg eax, DWORD PTR [edx+ebp*4]       ; if not in order then exchange them
    mov DWORD PTR [edx+ebp*4+4], eax    ; move eax to the next position for comparison
S1:
    add ebp,1                                                ; increment ebp
    cmp ebp,ecx                                             ; compares ebp to ecx
   jb bs_i                                                      ; repeat if not complete
    loop bs_o
    pop ebp     <<<<<<<<<<<<<<<< Why this HERE ??? <<<<<<<<<<<<

   call WriteHeader                                      ; writes the names to the menu

   call WaitMsg                                              ;"press any key to continue"
   ret                                                            ; return values to previous conditions
SortByLastName   ENDP

Could you explain why do you use «pop ebp» ?
Why do you use ebp and not ebx, for example ?
Title: Re: Help with Bubble Sorting in MASM
Post by: MASMClass on May 12, 2014, 06:42:07 AM
Alright, I threw out the old sorting procedure, and I am trying something new. I thought that this proc would work better, so I'm posting it now.
If you have any idea what is wrong with it, please describe to me in detail what it is. I'm still very new to MASM, and I don't know my way around it very well.

;-----------------------------------------------------------------------------------------------------------
SortByLastName PROC
;-----------------------------------------------------------------------------------------------------------
call Clrscr

_start:
   ;-----------------------
   ;Size of the array in
   ;ecx
   ;-----------------------
   mov ecx, LENGTHOF lnamearr
   mov ebp, LENGTHOF lnamearr
   mov ebx, [LENGTHOF lnamearr]
again:
   call bubble_sort
   dec ebp
   jnz again
   
   ;----------------
   ;Exit the program
   ;----------------
   mov eax, 1

   ;-------------------------------------...
   ;The base address of the array is in ebx
   ;The size of the array is in ecx
   ;-------------------------------------...
bubble_sort:
   push ebx
   push ecx
start_sorting:
   mov eax, [ebx]
   mov edx, [ebx+10]
   cmp eax, edx
   jg swap
   jmp next
swap:
   xchg eax, [ebx+10]
   mov [ebx], eax
next:
   add ebx, 10
   loop start_sorting
   pop ecx
   pop ebx
   ret
SortByLastName   ENDP


Just assume that I am only going to run this once, to switch two names around. i.e. The first and second last name are alphabetically incorrect, and I want to switch them.
The first name should be in [ebx 1-10] and the second should be in [ebx 11-20].
Thanks for all the help. It is greatly appreciated.
If preferred, I can also show my screen during a skype call, to work with any of you to make sure this gets done.
You see, this project is due tonight at 11:59 pm Central USA time. I am extremely desperate.
Title: Re: Help with Bubble Sorting in MASM
Post by: jj2007 on May 12, 2014, 08:05:20 AM
Quote from: MASMClass on May 12, 2014, 06:42:07 AM
   mov ebx, [LENGTHOF lnamearr]
...
   ;The base address of the array is in ebx

Sure?
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 12, 2014, 08:56:29 AM
Hi MASMClass

First: i dont like to use Irvine32 (i have no time to lose with it);

Second: you say, «The first name should be in [ebx 1-10] and
                  the second should be in [ebx 11-20].»
                 
        So, each has 10 bytes. If i am understanding the problem
        The Last Name starts at index EBX=10 and end at index EBX=19
        (10 bytes). So if what i am saying is correct, i dont understand
        why you compare only 4 bytes at a time, but we need to compare
        10 bytes, not 4 (and we need to change 10 bytes also, not 4).
       
        HERE:
                mov eax, [ebx]                 ; eax are only 4 bytes
                mov edx, [ebx+10]           ; edx are only 4 bytes
                cmp eax, edx
                ...
               
        It seems that each last name have only 4 bytes

Third: EBX must be the starting address of the last name array
           I dont understand this:

          «mov ebx, [LENGTHOF lnamearr]»

Try to see this:

_LastNameArray  db "This name1"         ; first name,  length=10    -> index 0
                            db "That name2"         ; second name, length=10    -> index 1
                and so on
                            db "Last nameN"         ; last name,   length=10    -> index N-1

The starting address:

                mov     esi, offset _LastNameArray
       
Number of names:
                mov     ecx, 20         ; 20 names for example
                mov     edx, 10         ; length of each name

                mov     ebx, esi
                add     ebx, edx        ; is the address of the second name

                mov     al, [esi]
                cmp     al, [ebx]       ; compare the first byte of the first name
                                        ; with the first byte of the second name
               
                and so on

               
    Think about this.
    Good luck  :t

;-----------------------------------------------------
SortByLastName PROC
;-----------------------------------------------------
call Clrscr

_start:
   ;-----------------------
   ;Size of the array in
   ;ecx
   ;-----------------------
   mov ecx, LENGTHOF lnamearr
   mov ebp, LENGTHOF lnamearr
   mov ebx, [LENGTHOF lnamearr]
again:
   call bubble_sort
   dec ebp
   jnz again
   
   ;----------------
   ;Exit the program
   ;----------------
   mov eax, 1

   ;-------------------------------------...
   ;The base address of the array is in ebx
   ;The size of the array is in ecx
   ;-------------------------------------...
bubble_sort:
   push ebx
   push ecx
start_sorting:
   mov eax, [ebx]
   mov edx, [ebx+10]
   cmp eax, edx
   jg swap
   jmp next
swap:
   xchg eax, [ebx+10]
   mov [ebx], eax
next:
   add ebx, 10
   loop start_sorting
   pop ecx
   pop ebx
   ret
SortByLastName   ENDP
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 12, 2014, 12:37:02 PM
i am a little surprised that none of the other members have addressed the overall design

normally, we might create a structure that contains all the entries for each student
when a new student record is added, it's always added at the end
currently, you have 10 + 10 + 4 + 4 bytes, or 28 bytes
well - you could use another entry for credit hours, as the current method doesn't allow the score to be updated
and, 10 characters for first and last name might be a bit limited
assuming those things are ok....
STUDENT_RECORD STRUCT
  dwStudentID dd ?
  dwScore     dd ?
  szLast      db 10 dup(?)
  szFirst     db 10 dup(?)
STUDENT_RECORD ENDS


now, rather than sorting records, we might create an index array
the array might be made of bytes that indicate a record index number (0 to 255)
or words or dwords, if more students are to be accommodated
the array might as well contain DWORD pointers to each record

you can create an array for each sort criteria, last name, first name, ID, score
rather than ordering the record array, you order the index array(s) according to sort criteria
this should be much more efficient, particularly if the number of records is large
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 12, 2014, 08:04:53 PM
 :biggrin:
Hi Dave,
      The overall design is not my problem and ...
      Well, write the procedures you need to solve it
      and help him, if you want Dave.
      I have no much time.

      You said: «...this should be much more efficient...»
      but he wants one way to solve the problem as far
      as i know. To start learning assembly
      we dont need to start doing complex things (my opinion).
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 12, 2014, 08:58:11 PM
i don't have a lot of spare time nowdays, either, Rui
but, i know what an instructor might like to see to get an A   :biggrin:
a basic indexed database is probably what he's after
it's a little tricky to order an index list - not the same as sorting the data, itself
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 12, 2014, 09:18:54 PM
Dave,

Quote from: dedndave on May 12, 2014, 08:58:11 PM
it's a little tricky to order an index list - not the same as sorting the data, itself

that's right. But I would write that in C or BASIC and translate it to assembly language later. With a high optimization level you have to give you a lot of effort to beat the compiler. It's possible, but not easy.

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 12, 2014, 09:20:47 PM
it's an assembly language class though, Gunther   :biggrin:

EDIT: earlier, i said that a new record always went at the end
but, it could be written so that deleted records remain, and a new one might replace a previously deleted one

now - all that may seem a little complicated
but, it's not a single programmer - it's a team
break it up and let each team member take a piece   :t
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 12, 2014, 09:31:41 PM
Dave,

Quote from: dedndave on May 12, 2014, 09:20:47 PM
it's an assembly language class though, Gunther   :biggrin:

yes, of course, but it's not forbidden to do the task at home first in C before you translate it into assembly language. If that's done, you have to set one compiler switch and you have the complete assembly language source. That would be my basis to work further. with gcc you must do:

gcc -S MySource.c

The compiler generates a file MySource.s which contains the compiler generated assembly source. With Borland it was -S too, I think. With Visual C exists a similar switch, I'm sure. So what?

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 12, 2014, 09:34:56 PM
Quote from: dedndave on May 12, 2014, 08:58:11 PM
i don't have a lot of spare time nowdays, either, Rui
but, i know what an instructor might like to see to get an A   :biggrin:
a basic indexed database is probably what he's after
it's a little tricky to order an index list - not the same as sorting the data, itself
Yes Dave, we can do it with linked list also, it is so easy and he gets AA!  :biggrin:
But Dave, you should explain to him what to do to get a indexed database.
Some time ago i posted something about it here.
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 12, 2014, 11:00:41 PM
in reply #8, i outlined it for him - you want me to write the code for him ? - lol
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 12, 2014, 11:55:10 PM
Quote from: dedndave on May 12, 2014, 11:00:41 PM
in reply #8, i outlined it for him - you want me to write the code for him ? - lol
No Dave, you can do only if you want, of course.

Here is a linked list example (it is in the old forum)
There are 3 fields: LkdData (80 bytes), StrData( 40 bytes), IntData (dword)
The data in linked list is only in LkdData,
StrData and IntData are not in linked list.
The example shows the structure (read it).
I think we can redefine the structure (try)
and we dont need to alloc memory for it
(NOTE: but the memory has a special structure!).
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 13, 2014, 01:30:27 AM
Hi MASMClass,
              i am reading (and learning ) what you did.

1.  If «maximum length of student name» is 10.

    we should do THIS:

MAXNUMST = 4                  ; maximum number of students that can be entered into database
NAMELEN = 10                  ; maximum length of student name
NAMELEN0    = NAMELEN + 1  ; maximum length of student name + NULL

lastname    BYTE NAMELEN0 DUP(0)
firstname   BYTE NAMELEN0 DUP(0)

lnamearr    BYTE MAXNUMST*NAMELEN0 DUP(0)   ; last name array
fnamearr    BYTE MAXNUMST*NAMELEN0 DUP(0)       ; first name array
stuidnum    DWORD MAXNUMST DUP(0)         ; student id array
avgscore    DWORD MAXNUMST DUP(0)         ; average score array

        If we want «maximum length of student name» is 9.
        DO
            NAMELEN = 9

       EDIT: i want NAMELEN and NAMELEN0 because i like to   
                work with NAMELEN, not with NAMELEN0.

2. We have 4 different arrays for each record.

   It means that when we do SortByLastName, we need
   change all other three in the same way.
   The same for SortByScore.

   So, we need one procedure to exchange 2 strings
   and another to exchange 2 dwords.
   
        Is it what you want to do ?
        Good luck !

Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 14, 2014, 01:56:49 AM
Hi
        I modified bubble_sort (MASM) to bubble_sortM
        and
        i wrote SortString which is bubble_sort for strings

       See the file below

        Here are the results:
        Good luck !  ;)


         EDIT: replace «jl» by «jle» to sort integers.       
Quote
Unsorted INTEGERS
1
9
2
8
3
7
4
6
5
0

Sorted INTEGERS- Bubble SORT
0
1
2
3
4
5
6
7
8
9
Unsorted STRINGS

Hutch
dedndave
MichaelW
Jochen
Gunther
Raymond
Farabi
Zen
minor28
RuiLoureiro
Press any key to continue ...

Sorted STRINGS- Bubble SORT

dedndave              <<<<<<<<<<<<<<<--- Hey, you are the first !
Farabi
Gunther
Hutch
Jochen
MichaelW
minor28
Raymond
RuiLoureiro
Zen
Press any key to continue ...
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 14, 2014, 02:28:17 AM
looks good, Rui   :t
some time back, i needed an index sort - can't remember what it was for - lol
if i could remember, i could find the source for it
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 14, 2014, 05:07:48 AM
Hi Rui,

good and illustrating example.  :t

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: minor28 on May 14, 2014, 06:01:15 PM
I do not know if bubble sorting is the same as heap sorting but heap sorting is how I sort and search in lists.
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 15, 2014, 03:02:51 AM
Quote from: minor28 on May 14, 2014, 06:01:15 PM
I do not know if bubble sorting is the same as heap sorting but heap sorting is how I sort and search in lists.
It doesnt seem to be the same.
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 15, 2014, 03:05:11 AM
Hi

    This is the new linked list file LkdList5.asm
    Now it works with 4 fields in linked list and ...

    See the file LkdList5.zip (asm,exe) and test it.
    I tried to explain a lot of things in the file .asm.

    Good luck !   
    RuiLoureiro
   
Quote
        We may create a linked list database with 4 fields in linked_list:

            First  field X: LkdDataX   -> is a string field

            Second field Y: LkdDataY   -> is a string field

            Third  field I: LkdDataI   -> is an integer field

            Fourth field K: LkdDataK   -> is an integer field

            These fields are defined in the NODE structure we can see below.
           
            These names (LkdDataX,LkdDataY,LkdDataI,LkdDataK) are used in
            the written procedures, so we cannot redefine it.

            We may add some other like StrData for strings or IntData for
            integers. But these are not in linked_list. They stay only
            in the records.

      -----------------------------
      CREATING A DATABASE
      -----------------------------
     
            1. Define NumOfRecords ( LenOfRecords is defined in NODE)

            2. call
           
            invoke   CreateLkdList, NumOfRecords, LenOfRecords, addr pBuffer, addr pList

            3. before exiting, call

                invoke   DestroyLkdList, pBuffer

    --------------               
         OR
    -------------       

            1. We use _LkdDataXBase defined in .DATA

            2. call
           
                invoke  FormatLkdList, NumOfRecords, pList

      --------------------------------------------
      INSERTING DATA INTO A DATABASE
      --------------------------------------------

        First, insert into field X using InsertLkdListX because only
        this procedure alloc one free record (the others dont alloc)
     
            invoke   InsertLkdListX, pList, addr Frut1          ; insert string

        Second, insert any other by any order
           
            invoke   InsertLkdListY, pList, addr Str1           ; insert string           
            invoke   InsertLkdListI, pList, Val1                ; insert integer
            invoke   InsertLkdListK, pList, 20                  ; insert integer

        Third, add any other
       
            invoke   AddStrLkdList, pList, NODE.StrData, addr Str1      ; string
            invoke   AddIntLkdList, pList, NODE.IntData, Val1           ; integer

      --------------------------------------------
      DELETING DATA FROM A DATABASE
      --------------------------------------------
     
            Use DeleteLkdListX  or DeleteLkdListY or DeleteLkdListI or DeleteLkdListK

            They try to find the string or integer and remove the record from the
            database. They don't wait for an answer, so it is not the best way, but...
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 25, 2014, 12:12:41 AM
Hi

***--The Linked List Database --***
       
        I wrote a set of basic procedures to build a
        complete linked list database (LkdList6.inc).

        I wrote an example program that shows how
        to use the procedures (LkdList6.asm).

        For detailed information, read LkdList6.txt
       
        If you don't mind, try to test it and
        say something about it.

        Good luck !
        RuiLoureiro

Quote
        NOTE: Soon, i will post a complete example.
              You may write your own example, easily.

        Files:
                LkdList6.inc <---- set of basic procedures
                LkdList6.glb  ----  global (protos ...)
                LkdList6.mac  ----  macros
                LkdList6.dat  ----  test data
                LkdList6.txt <---- text about basic information

                LkdList6.asm <---- basic example
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 25, 2014, 02:21:53 AM
Rui,

well done.

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 25, 2014, 09:30:09 PM
hutch:

I know that I've been exiled to the 16 bit DOS Programming thread of this forum but this problem interests me right now because one of the things I use my Advanced Data Access method (ADAM) is as a sorter. Unfortunately I am in the middle of converting it to MASM32 so it probably can't help with this problem until I get it finished. I should be finished in a week or so. How I sorted records using ADAM was to build a record with a key in the order that I wanted it sorted, created an ADAM file using ADAMCREA.exe with that key, added the records I built in random order to the ADAM file using ADAMACMD, and then read them back in sequential order because  ADAM has them all sorted by key. An example would be if you want your records sorted by last name, first name, and social security number (in case you could have duplicate first and last name), you could build them with a key of last name say 30 characters, first name 30 characters, and social security number 9 characters which gives you a key 69 characters long. Create an ADAM file using the program ADAMCREA,exe to build a file with the 69 characters in the first position (the key) plus the record length, however long, so the ADAM record length would be your record length plus 69. Add them to the file that you created in random order using ADAMACMD and, VIOLA! read them back all sorted in sequential order using ADAMACMD.

I won't be too much longer with the conversion from 16 bit DOS to MASM32 but I have a question. Under DOS you use the ES:SI registers to point at the source for a move to the address in the DS:DI registers. You move a field of data from one segment to another. Under MASM 32, since the ESI and EDI registers are now 32 bits long, does it even matter what the ES register and the DS point to?  :icon_confused: I don't think so because in MASM32 everything in a program is linked together in one up to 4 gigabyte "segment!"  :biggrin:

Will
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 25, 2014, 09:40:45 PM
it's DS:SI / DS:ESI and ES:DI / ES:EDI
in win32, all addresses are 32 bits in size, so you must use ESI and EDI
and - right, with a Flat memory model, CS = DS = ES = SS, no need to mess with the segment registers

EDIT: in truth, the segment registers are not pointers to physical segments anymore
they are, instead, pointers to tables with physical memory maps
so, the values in the segment registers may not be the same
but, they point to the same virtual memory
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 25, 2014, 09:41:10 PM
Will,

I assume you're talking about the string instructions. Here's the description of STOS from the Intel Manual, Vol. 2B, p. 4-444:
Quote
In non-64-bit and default 64-bit mode; stores a byte, word, or doubleword from the AL, AX, or EAX register (respectively) into the destination operand. The destination operand is a memory location, the address of which is read from either the ES:EDI or ES:DI register (depending on the address-size attribute of the instruction and the mode of operation). The ES segment cannot be overridden with a segment override prefix.

At the assembly-code level, two forms of the instruction are allowed: the "explicit-operands" form and the "nooperands" form. The explicit-operands form (specified with the STOS mnemonic) allows the destination operand to be specified explicitly. Here, the destination operand should be a symbol that indicates the size and location of the destination value. The source operand is then automatically selected to match the size of the destination operand
(the AL register for byte operands, AX for word operands, EAX for doubleword operands). The explicit-operands form is provided to allow documentation; however, note that the documentation provided by this form can be misleading. That is, the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword), but it does not have to specify the correct location. The location is always specified by the ES:(E)DI register. These must be loaded correctly before the store string instruction is executed.

The no-operands form provides "short forms" of the byte, word, doubleword, and quadword versions of the STOS instructions. Here also ES:(E)DI is assumed to be the destination operand and AL, AX, or EAX is assumed to be the source operand. The size of the destination and source operands is selected by the mnemonic: STOSB (byte read from register AL), STOSW (word from AX), STOSD (doubleword from EAX). After the byte, word, or doubleword is transferred from the register to the memory location, the (E)DI register is incremented or decremented according to the setting of the DF flag in the EFLAGS register. If the DF flag is 0, the register is incremented; if the DF flag is 1, the register is decremented (the register is incremented or decremented by 1 for byte operations, by 2 for word operations, by 4 for doubleword operations).

HTH
Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 25, 2014, 11:38:20 PM
Quote from: dedndave on May 25, 2014, 09:40:45 PM
it's DS:SI / DS:ESI and ES:DI / ES:EDI
in win32, all addresses are 32 bits in size, so you must use ESI and EDI
and - right, with a Flat memory model, CS = DS = ES = SS, no need to mess with the segment registers

EDIT: in truth, the segment registers are not pointers to physical segments anymore
they are, instead, pointers to tables with physical memory maps
so, the values in the segment registers may not be the same
but, they point to the same virtual memory

You're right, I got the register notation backward in my post. But I do have to "mess" with the ES and DS registers because that's the way ADAM works in DOS and it'll be the same in MAS32. What we are talking about here is that I have to set the ES:EDI registers to point to the ADAM .data and the DS:ESI to the user .data when writing a record for the user and the opposite when reading a record for the user. I had to do the same thing when I originally wrote ADAM in 1982, except it was DS:SI and ES:DI. Actually, it makes the convert easier because it already works under DOS, just change the SI and DI registers to ESI and EDI   :t
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 26, 2014, 12:47:57 AM
Will,

Quote from: Will on May 25, 2014, 11:38:20 PM
... and it'll be the same in MAS32. What we are talking about here is that I have to set the ES:EDI registers to point to the ADAM .data and the DS:ESI to the user .data when writing a record for the user and the opposite when reading a record for the user.

No. Don't touch the segment registers under a Protected Mode Operating System. You have to point ESI to the source and EDI to the destination. That's all. It's high time to understand that.

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 26, 2014, 01:15:58 AM
Quote from: Gunther on May 26, 2014, 12:47:57 AM
Will,

No. Don't touch the segment registers under a Protected Mode Operating System. You have to point ESI to the source and EDI to the destination. That's all. It's high time to understand that.

Gunther

Gunther:

What you don't seem to understand is that if you call ADAM you had better be in the same protected mode memory as ADAM is. You link them together and that will take care of the problem. Back in 1982 there was no memory protect mode but I still had to work out how to call ADAM from a program. I had to figure out how to adjust the ES and DS registers so the string move instructions would work properly. You also don't seem to know that for years starting in 1969, long before PCs were around, I "Systems Programmed" on the IBM 360 system which was a 32 bit memory protected machine. I don't think that, without that experience, I ever could have written ADAM. Talk to an IBM assembler language programmer and you'll find out that the new PC architecture  is very similar to the IBM mainframe architecture from way before the PC X86 processors were even thought of.  8)
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 26, 2014, 01:43:26 AM
Will,

Quote from: Will on May 26, 2014, 01:15:58 AM
Gunther:

What you don't seem to understand is that if you call ADAM you had better be in the same protected mode memory as ADAM is.

the question is: Do you understand what I'm talking about?

Do you really think you're the only mainframe programmer in the world? Hutch and me - and probably others too - did start the career as coder with mainframe programming. It's true that a lot of principles are adopted from mainframes to the todays PCs. But there are a lot of principle differences, too. The IBM 360 series was a CISC computer with 16 32-bit registers and 4 64-bit floating point registers as a time-sharing system. It was first MFT (Multiprogramming with a fixed number of tasks) and became later a MVT (Multiprogramming with a variable number of tasks). But that was another approach.

You don't know not much about Protected Mode. The trick is: All your code and data are inside the same segment (memory range). As a beginner you should not touch the segment registers. That's what we've written to you several times: for example here (http://masm32.com/board/index.php?topic=3147.msg32644#msg32644) and here (http://masm32.com/board/index.php?topic=3147.msg32756#msg32756). But you should follow that hints and read that stuff, at least.

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 26, 2014, 03:19:28 AM
what Will is missing is the fact that his old code had a 640 Kb limit
and, under win32, we might move more than 640 Kb from one place to another inside a single workspace   :P

you can play with DS and ES if you like, but be prepared for a crashing program
the only "segment register" i have had to deal with under win32 is FS
and, then, i haven't had to modify it - just change the ASSUME   :biggrin:
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 26, 2014, 03:54:49 AM
Hi Will

    You say:
Quote
                «I have to set the ES:EDI registers to point to the ADAM .data
                and
                the DS:ESI to the user .data when writing a record for the user
                and
                the opposite when reading a record for the user»
It seems that you think that ES:EDI registers to point to
        "a protected memory" the ADAM .data.
        and
        the DS:ESI to "an unprotected memory" the user .data.
                   
        One question: What's the problem if ES=DS ?
        Could you explain ?
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 26, 2014, 04:22:02 AM
Hi Will,

Quote
How I sorted records using ADAM was
to build a record with a key

in the order that I wanted it sorted,
created an ADAM file using ADAMCREA.exe with that key,
added the records

I built in random order to the ADAM file using ADAMACMD, and then read them back
in sequential order because  ADAM has them all sorted by key.

            It seems that:
           
                1. When we want to create a database, we put the records
                   one after another.

                2. When we want to search for ...???... we use ADAMCREA.exe
                   etc. etc. and then we have it sorted.

                3. And we may show it...

            Is this correct, Will ?
            If it is correct, i would say that i never would use it.
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 26, 2014, 05:40:55 AM
Quote from: Gunther on May 26, 2014, 01:43:26 AM
Will,

Quote from: Will on May 26, 2014, 01:15:58 AM
Gunther:

What you don't seem to understand is that if you call ADAM you had better be in the same protected mode memory as ADAM is.

the question is: Do you understand what I'm talking about?

You don't know not much about Protected Mode. The trick is: All your code and data are inside the same segment (memory range). As a beginner you should not touch the segment registers.
Gunther

Gunther - Isn't that what I said? when you link one of the ADAM subroutines with a program that uses it, you link them together as in the following:

LINK /SUBSYSTEM:CONSOLE myprogram ADAM(SUBROUTINE) ENTRY:(myprogram entry point)

If I get everything for my line editor converted to MASM32 it will be linked as follows:

LINK /SUBSYSTEM:CONSOLE EDLINAS ADAMACRM ADAMALDM ADAMACMD /ENTRY:BEGIN (BEGIN IS THE ENTRY POINT TO EDLINAS, my line editor).

That way all of myprogram and all of the ADAM subroutine are in the same memory "segment" so protected memory is not a problem. I've already encountered the problem and spent a day figuring out that "The program has encountered a problem and needs to close" meant what would be called a "protection exception" on a mainframe. (I accidentally accessed memory that was not in the same memory "segment" as my program.)
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 26, 2014, 06:03:27 AM
Quote from: RuiLoureiro on May 26, 2014, 04:22:02 AM
Hi Will,
            It seems that:
           
                1. When we want to create a database, we put the records
                   one after another.

                2. When we want to search for ...???... we use ADAMCREA.exe
                   etc. etc. and then we have it sorted.

                3. And we may show it...

            Is this correct, Will ?
            If it is correct, i would say that i never would use it.

Ruil: not exactly.
                           1 - Use ADAMCREA.exe to create the ADAM file with a key that you want to sort records into.
                           2 - Use a program to call ADAMACMD to add the records in random order by the key    sequence that you want them sorted into.
                           3 - Use ADAMACMD to read them back in the sequential order that you wanted to sort them                                           into.
                    and 4 - If you want, you can read, write, add, and/or erase records in random, forward, or backward order .  :t
Title: Re: Help with Bubble Sorting in MASM
Post by: RuiLoureiro on May 26, 2014, 06:38:37 AM
Will,
         I hope you translate your DOS to WIN32 and post it here.
         I would like to read it... and i would like
         to see how it works.
         The names itself never say anything to me.
         That's all.  :t
Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 26, 2014, 07:59:53 AM
Will,

Quote from: Will on May 26, 2014, 05:40:55 AM
LINK /SUBSYSTEM:CONSOLE myprogram ADAM(SUBROUTINE) ENTRY:(myprogram entry point)

that's exactly the point. With SUBSYSTEM:CONSOLE your application is a 32-bit Protected Mode console application. That is: DS = ES (contain the same selector, which is a pointer to a segment descriptor). The only thing what you've to do is to change ESI and EDI, not more, because DS and ES have already the appropriate value. That was my point.

Gunther
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 26, 2014, 09:57:35 AM
Quote from: Gunther on May 26, 2014, 07:59:53 AM
Will,

Quote from: Will on May 26, 2014, 05:40:55 AM
LINK /SUBSYSTEM:CONSOLE myprogram ADAM(SUBROUTINE) ENTRY:(myprogram entry point)

that's exactly the point. With SUBSYSTEM:CONSOLE your application is a 32-bit Protected Mode console application. That is: DS = ES (contain the same selector, which is a pointer to a segment descriptor). The only thing what you've to do is to change ESI and EDI, not more, because DS and ES have already the appropriate value. That was my point.

Gunther

Gunther - the way that ADAM operates on a DOS system is similar to the way it will operate on a Win32 system It gets it's memory with an interrupt on the DOS system and will have to get memory on the Win32 system using "heap" functions. I designed it originally to use available memory to do it's thing. I'll have to do the same with Win32 according to my reading. Anyway, in most programs, the DS and ES registers point to the same date area. When you call ADAM to create, load, or access a file it has to get memory. The result is that the ES and  DS registers have to be manipulated to move records and other information from and to the users memory with the ES:DI and DS:SI registersunder DOS. Under Win32 it will use the ES:EDI and DS:ESI registers. the ES and DS registers are changed depending on whether ADAM is moving information to or from the users .data. I did it that way back when I was writing version 1 of ADAM. The same thing applies to verson 2 on Win32. Now, after over twenty years, I'm converting ADAM from DOS 16 bit to MASM 32 bit. Don't worry, I know what I'm doing and I'll thoroughly test it before I allow anybody to use it.  8)
Title: Re: Help with Bubble Sorting in MASM
Post by: Will on May 26, 2014, 10:11:49 AM
Quote from: RuiLoureiro on May 26, 2014, 06:38:37 AM
Will,
         I hope you translate your DOS to WIN32 and post it here.
         I would like to read it... and i would like
         to see how it works.
         The names itself never say anything to me.
         That's all.  :t

How it works is a trade secret that I plan to keep to myself. What it will do, I've tried to explain to people. Let's just say that if you need something to create a data base system, it's the best there is. Unfortunately, I've been distracted now for over twenty years so I've just recently gotten around to converting it to 32 bit code. I'm even looking ahead and expect that, if things go right, version 3 will be a 64 bit data base system and those who have "Cloud" compuying systms will have a real competitor.  :t
Title: Re: Help with Bubble Sorting in MASM
Post by: dedndave on May 26, 2014, 02:10:24 PM
i can well imagine it goes something like this...

you pass a segment
the base offset (SI or DI) is 0, resulting in a SEG:0 arrangement

eventually, you'll have convert those terms into a base address that is not 0   :P
you can trust me on this
Title: Re: Help with Bubble Sorting in MASM
Post by: MichaelW on May 26, 2014, 04:08:54 PM
Quote from: Will on May 26, 2014, 09:57:35 AM
When you call ADAM to create, load, or access a file it has to get memory. The result is that the ES and  DS registers have to be manipulated to move records and other information from and to the users memory with the ES:DI and DS:SI registers under DOS. Under Win32 it will use the ES:EDI and DS:ESI registers. the ES and DS registers are changed depending on whether ADAM is moving information to or from the users .data.

In a Windows application any attempt to load anything other than a valid selector (or a null selector, but that presents other problems) into a segment register will trigger an exception, and Windows will solve the problem by terminating your application.

Demo.asm:

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
    .code
;==============================================================================
start:
;==============================================================================
    ; Display the selector in DS and ES:
    mov bx, es
    movzx ebx, bx
    printf("%04Xh\n",ebx)
    mov ax, es
    movzx eax, ax
    printf("%04Xh\n",eax)
    ; Increment the selector value and display it:
    inc ebx
    printf("%04Xh\n",ebx)
    inkey "Press any key to trigger an exception..."
    ; Now try to load the selector into ES:
    mov es, bx
;==============================================================================
end start


0023h
0023h
0024h
Press any key to trigger an exception...


The above shows that DS and ES have the same selector, so they both have the same segment base, limit, and access rights, and therefore can be used to access anywhere in the accessible address space.

And here are the essential parts of the DrWatson crash dump:

Application exception occurred:
        App: C:\masm32\My\NewSegRegs\demo.exe (pid=2580)
        When: 5/26/2014 @ 00:53:59.079
        Exception number: c0000005 (access violation)

*----> System Information <----*
...
*----> Task List <----*
...
2580 demo.exe
196 drwtsn32.exe
*----> Module List <----*
(0000000000400000 - 0000000000404000: C:\masm32\My\NewSegRegs\demo.exe
(0000000077b40000 - 0000000077b62000: C:\WINDOWS\system32\Apphelp.dll
(0000000077c00000 - 0000000077c08000: C:\WINDOWS\system32\VERSION.dll
(0000000077c10000 - 0000000077c68000: C:\WINDOWS\system32\msvcrt.dll
(0000000077dd0000 - 0000000077e6b000: C:\WINDOWS\system32\ADVAPI32.dll
(0000000077e70000 - 0000000077f03000: C:\WINDOWS\system32\RPCRT4.dll
(0000000077f10000 - 0000000077f59000: C:\WINDOWS\system32\GDI32.dll
(0000000077f60000 - 0000000077fd6000: C:\WINDOWS\system32\SHLWAPI.dll
(0000000077fe0000 - 0000000077ff1000: C:\WINDOWS\system32\Secur32.dll
(000000007c800000 - 000000007c8f6000: C:\WINDOWS\system32\kernel32.dll
(000000007c900000 - 000000007c9b2000: C:\WINDOWS\system32\ntdll.dll
(000000007e410000 - 000000007e4a1000: C:\WINDOWS\system32\USER32.dll

*----> State Dump for Thread Id 0x8f8 <----*

eax=00000002 ebx=00000024 ecx=7c81138e edx=7c90e514 esi=00340036 edi=00320035
eip=00401053 esp=0012ffc4 ebp=0012fff0 iopl=0         nv up ei pl zr na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

*** WARNING: Unable to verify checksum for C:\masm32\My\NewSegRegs\demo.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\masm32\My\NewSegRegs\demo.exe
function: demo
        0040102d 1030             adc     [eax],dh
        0040102f 40               inc     eax
        00401030 00ff             add     bh,bh
        00401032 151c204000       adc     eax,0x40201c
        00401037 83c408           add     esp,0x8
        0040103a 6818304000       push    0x403018
        0040103f e814000000       call    demo+0x1058 (00401058)
        00401044 e847000000       call    demo+0x1090 (00401090)
        00401049 6841304000       push    0x403041
        0040104e e805000000       call    demo+0x1058 (00401058)
FAULT ->00401053 668ec3           mov     es,bx
        00401056 cc               int     3
        00401057 cc               int     3
        00401058 55               push    ebp
        00401059 8bec             mov     ebp,esp
        0040105b 83c4f4           add     esp,0xfffffff4
        0040105e 6af5             push    0xf5
        00401060 e8cd000000       call    demo+0x1132 (00401132)
        00401065 8945fc           mov     [ebp-0x4],eax
        00401068 ff7508           push    dword ptr [ebp+0x8]
        0040106b e850000000       call    demo+0x10c0 (004010c0)


So given that the DS and ES (and also SS) segment registers all "point" to the same segment, when manipulating data there is no need to modify or even specify a segment register. And while MOVS_ and similar instructions are hardwired to use ESI and EDI, in 32-bit code (or 16-bit code using 32-bit instructions) indirect memory operands can use any general-purpose register as a base register or an index register.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
HEXDUMP MACRO address, paragraphs, zerobase
    invoke HexAsciiDump, address, paragraphs, zerobase
ENDM
hexdump equ HEXDUMP
;==============================================================================
    .data
    .code
;==============================================================================
;-----------------------------------------------------------------------
; This longer name avoids a conflict with the MASM32 HexDump procedure.
;-----------------------------------------------------------------------
HexAsciiDump proc startAddress:DWORD, nParagraphs:DWORD, fZeroBase:DWORD
    push ebx
    push edi
    push esi
    mov esi, startAddress
    xor ebx, ebx
    .WHILE ebx < nParagraphs
        mov eax, esi
        mov ecx, ebx
        shl ecx, 4
        .IF fZeroBase
            printf( "%08X  ", ecx )
        .ELSE
            add eax, ecx
            printf( "%08X  ", eax )
        .ENDIF
        xor edi, edi
        .WHILE edi < 16
            mov ecx, ebx
            shl ecx, 4
            add ecx, edi
            movzx eax, BYTE PTR [esi+ecx]
            printf( "%02X ", eax )
            .IF edi == 7
                printf( "- " )
            .ENDIF
            inc edi
        .ENDW
        printf( "  " )
        xor edi, edi
        .WHILE edi < 16
            mov ecx, ebx
            shl ecx, 4
            add ecx, edi
            movzx eax, BYTE PTR [esi+ecx]
            .IF eax > 31 && eax < 127
                printf( "%c", eax )
            .ELSE
                printf( "." )
            .ENDIF
            inc edi
        .ENDW
        printf( "\n" )
        inc ebx
    .ENDW
    pop esi
    pop edi
    pop ebx
    ret
HexAsciiDump endp
;==============================================================================
start:
;==============================================================================
    invoke GetProcessHeap
    mov ebx, eax

    invoke HeapAlloc, ebx, HEAP_ZERO_MEMORY, 16
    mov esi, eax
    hexdump esi, 1, 0

    invoke HeapAlloc, ebx, HEAP_ZERO_MEMORY, 16
    mov edi, eax
    hexdump edi, 1, 0

    xor eax, eax
    mov ecx, 16
  @@:
    dec ecx
    mov [esi+ecx], cl
    jnz @B
    hexdump esi, 1, 0

    push esi
    push edi
    mov ecx, 16
    rep movsb
    pop edi
    pop esi
    hexdump edi, 1, 0

    mov edx, edi
    mov ecx, 15
  @@:
    add BYTE PTR [edx+ecx], 1
    dec ecx
    jns @B
    hexdump edx, 1, 0

    mov edx, esi
    mov eax, -1
    mov ecx, 4
  @@:
    dec ecx
    mov [edx+ecx*4], eax
    jnz @B
    hexdump edx, 1, 0

    printf("\n")

    invoke HeapFree, ebx, 0, esi
    invoke HeapFree, ebx, 0, edi

    inkey
    exit
;==============================================================================
end start


001432D8  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
001432F0  00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00   ................
001432D8  00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F   ................
001432F0  00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F   ................
001432F0  01 02 03 04 05 06 07 08 - 09 0A 0B 0C 0D 0E 0F 10   ................
001432D8  FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF   ................


Title: Re: Help with Bubble Sorting in MASM
Post by: Gunther on May 26, 2014, 05:42:13 PM
Quote from: MichaelW on May 26, 2014, 04:08:54 PM
In a Windows application any attempt to load anything other than a valid selector (or a null selector, but that presents other problems) into a segment register will trigger an exception, and Windows will solve the problem by terminating your application.

that's exactly what will happen. But please ignore us, Will, it's your freedom.

But let me say this: It isn't necessary to change a segment register. You don't know what Protected Mode is, you  know nothing about Protected Mode principles, behavior, the ring concept etc. etc. But you would like to change segment registers? Fine, good luck.

Gunther