; Program asks for a string of up to 20 digits
; It sorts them from low to high and prints
; them (with no spaces)


IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
arrsz  db ?
Text   db 'Please enter up to 20 digits:$'
number db 23 dup(?)

; --------------------------
CODESEG

;*******************************************************************************
proc          newline
              push ax   ; ax = 100  (0064h)
              push dx   ; dx = 30
    		  mov  ah,2 ; ax 0264              
	          mov  dl,10
		      int  21h
		      pop  dx   ; dx = 30
		      pop  ax   ; ax = 100
		      ret
endp          newline
;*******************************************************************************
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
; --------------------------
;printing the instruction
	mov dx, offset Text
	mov ah, 9h
	int 21h
;
	call newline
	                       ;inputting digits from the user
	mov dx, offset number
	mov bx, dx
	mov [byte ptr bx], 21
	mov ah, 0ah
	int 21h
	call newline
	;sorting the digits
	mov bx, offset number
	add bx,1
	mov al,[byte ptr bx]   ; number of input digits
	mov [arrsz],al
	mov ah,0
	push ax
	add bx,1
	push bx                ; array's address (first element)
	call sortarray
	add bl,[arrsz]
	mov [byte ptr bx],'$'  ; put the $ at the end of the printed line
	                       ; print sorted array
	mov dx, offset number
	add dx,2
	mov ah,9h
	int 21h
	
; --------------------------
exit:
	mov ax, 4c00h
	int 21h
END start			