;--------------------------------------------------------------------------------
; Sort the elements of an array, using several procedures
; Barak Gonen 2015
;--------------------------------------------------------------------------------
IDEAL
MODEL small
STACK 100h

DATASEG
msg	db 'Please enter a digit, x to finish$'
ArrayLength dw (?)
Array db 100 dup (?)

CODESEG
start:
	mov 	ax, @data
	mov 	ds, ax
	; input numbers from user (0-9 only, to make it simple)
	push 	offset msg
	push 	offset Array
	push 	offset ArrayLength
	call 	Kelet
	; pass parameters and call sort procedure
	push 	offset Array
	push 	offset ArrayLength
	call 	SortArray
	; print results (works only for digits 0-9)
	; new line
	mov		ah, 2h
	mov		dl, 10
	int 	21h
	mov		dl, 13
	int		21h
	mov 	bx, offset Array
	mov 	ah, 2
	mov 	cx, [ArrayLength]
print:
	mov 	dl, [bx]
	add 	dl, '0'
	int 	21h
	inc 	bx
	loop 	print
exit:
	mov 	ax, 4C00h
	int 	21h
	
proc Kelet
	MESSAGE 	equ [bp+8]
	ARRAY_INPUT	equ [bp+6]
	ARRAY_LENGTH equ [bp+4]
	push 	bp
	mov		bp, sp
	; save registers
	push	bx
	push	si
	push	dx
	push	ax
	; initialize
	mov		bx, ARRAY_INPUT
	mov		si, ARRAY_LENGTH
user_input_loop:	
	mov		dx, MESSAGE
	mov		ah, 9h
	int		21h
	mov		dl, ' '
	mov		ah, 2h
	int		21h
	mov		ah, 1h
	int		21h
	cmp		al, 'x'
	je		end_input
	sub		al, '0'
	mov		[bx], al
	inc 	bx
	inc		[word ptr si]
	; new line
	mov		ah, 2h
	mov		dl, 10
	int 	21h
	mov		dl, 13
	int		21h
	jmp		user_input_loop
end_input:
	; restore registers
	pop		ax
	pop		dx
	pop		si
	pop		bx
	pop		bp
	ret		6
endp Kelet

Proc SortArray
; Sort an array
; Input - pointer to an array, number of elements in the array
	; set BP
	ArrOffset 	equ [bp+6]  
	num 		equ [bp+4]
	push 	bp 
	mov 	bp, sp
	; store the registers
	push 	ax
	push 	bx
	push 	si
	push 	cx
	; initialize
	mov 	bx, ArrOffset 	; offset of the first element
	mov		si, num			; number of elements in the array
	mov 	cx, [si] 		
	; sort
SortLoop:
	cmp 	cx, 1
	je 		fin
	push 	bx
	push 	cx
	call 	FindMin
	push 	si
	push 	bx
	call 	Swap
	inc 	bx
	dec 	cx
	jmp 	SortLoop
fin:
	; restore registers
	pop 	cx 
	pop 	si
	pop 	bx
	pop 	ax
	pop 	bp
	Ret 	4 
EndP SortArray

Proc FindMin
; Find the minimal element of an array
; Input- pointer to an array and number of elements
; Output- index of the minimal element of the array, in register si
	; set BP
	push 	bp
	mov 	bp, sp
	; store the registers
	push 	ax 
	push 	bx
	push 	cx
	; initialize 
	mov 	bx, ArrOffset 	; offset of the first element
	mov 	al, [bx] 		; value of the first element
	mov 	si, bx
	inc 	bx
	mov 	cx, num 		; number of elements in the array
	dec 	cx
MinLoop:
	cmp 	al, [bx]
	jng 	next
	mov 	al, [bx]
	mov 	si, bx
	next:
	inc 	bx
	loop 	MinLoop
	; restore registers
	pop 	cx 
	pop 	bx
	pop 	ax
	pop 	bp
	Ret 	4
EndP FindMin

Proc Swap
; Swap the values of two parameters
; Input- pointers to two elements (pass by reference)
	; set BP
	offset1 	equ [bp+6]  
	offset2 	equ [bp+4]
	push 	bp
	mov 	bp, sp
	; store the registers
	push 	ax 
	push 	bx
	push 	si
	; swap values
	mov 	bx, offset1
	mov 	si, offset2
	mov 	ah, [bx]
	mov 	al, [si]
	mov 	[bx], al
	mov 	[si], ah
	; restore registers
	pop 	si 
	pop 	bx
	pop 	ax
	pop 	bp
	Ret 	4
EndP Swap
	
END start