; Participant: Jacob Shutzman / exe. 9.8 B - Page 186 in the text book.
; (sorting an array of numbers with 2 specific procedures: findmin / swap)

; The procedure findmin finds the index of the minimum value in an array
; The procedure swap receives 2 memory locations, and swaps the values in them
; The procedure sortarray 'orchestrates' the sorting using the above two, with 
; the method described, in which we scan the remaining array to look for minimum.
; and swap it with the 'current' first element.


IDEAL
MODEL small
STACK 20h
DATASEG
num_elem      equ 10                       ; sample of an array of 10
arr1          db  9,8,7,6,5,1,0,18,11,13
 
CODESEG
;*******************************************************************************
proc          findmin    ; The return value (index of the minimum) will be in ax
              push bp
              mov  bp,sp 
; save registers used in proc, to be restored upon return to the main program
              push cx
              push dx
              push si
;-------------------------------------------------------------------------------        
              mov  cx,[bp+6]   ; array size (to be used as loop counter)
              mov  bx,[bp+4]   ; array's address
              xor  dx,dx
              xor  ax,ax
              mov  dl,[byte ptr bx]     ; dl will have the minimum value
              mov  si,1
loop1:        cmp  dl,[byte ptr bx+si]  
              jl   cont
              mov  dl,[byte ptr bx+si]
              mov  ax,si                ; ax will have the index of the minimum
cont:         inc  si
              loop loop1
; restore registers to the way they were before calling the proc
              pop  si
              pop  dx
              pop  cx
;-------------------------------------------------------------------------------
              pop  bp
              ret  4
endp          findmin 
;*******************************************************************************
proc          swap             ;exchanges value of two parameters passed by ref.
              push bp
              mov  bp,sp       ;bx will be used to address the variables.
; save registers used in proc, to be restored upon return to the main program
			  push bx
			  push dx
			  push si
;-------------------------------------------------------------------------------			
              mov  bx,[bp+6]              ; var1's address was pushed first 
              mov  al,[byte ptr bx]       ; value of var1
              mov  si,bx                  ; si keeps var1's Address 
              mov  bx,[bp+4]      
              mov  dl,[byte ptr bx]       ; value of var2 to dl
              mov  [si],dl                ; exchange
              mov  [bx],al       
; restore registers to the way they were before calling the proc, upon return.
			  pop  si
			  pop  dx
			  pop  bx
;-------------------------------------------------------------------------------           
              pop bp
              ret 4
endp          swap
;*******************************************************************************
proc          sortarray        ; exchange value of two parameters passed by ref.
              push bp
              mov  bp,sp 
              push bx          ; save regs
              push ax
              push cx
              push si         
              mov  bx,[bp+4]   ; address of the beginning of the array
              mov  si,[bp+6]   ; The size of the array to sort
              dec  si          ; array's index starts from zero, so last index
              mov  cx,si       ; is size - 1. 
sortloop:     push si
              push bx
              call findmin     ; ax will have the index of the min. (returned)
              add  ax,bx       ; calculate the address of the min elem because
                               ; bx has the address of the first element.

; if ax is equal to bx  meaning the first element is also the minimum in the
; remaining array, no need to swap. This saves some time.

              cmp  ax,bx
              je   contin 
              push ax
              push bx                                          
              call swap
contin:       inc  bx          ; Advance to next element (byte array)
              dec  si          ; The remaining array has one less element 
              loop sortloop
              pop  si          ; restore regs
              pop  cx
              pop  ax
              pop  bx
              pop  bp
              ret  4
endp          sortarray
;*******************************************************************************
start:        mov ax, @data
              mov ds, ax
;-----------------------------  sorting the array ------------------------------
              mov  ax,num_elem 
              push ax          ;array size
              lea bx,[arr1]    ;address where the array arr1 begins
              push bx   
              call sortarray
;------------------------------
;print the array
			  mov  cx,num_elem
			  dec  cx
			  lea  bx,[arr1]
			  xor  si,si
prtloop:      mov  dl,[bx+si]
			  mov  ah,2h
			  int  21h
			  inc  si
			  loop prtloop
;------------------------------

exit:         mov ax, 4c00h
              int 21h
END start   