# --------------------------------------------------------------------
# showStats.s
#	Find & display the sum and average of a list of integers.
# Takes 2 arguments: address of int array, number of ints in array.
# Returns void.
# ....................................................................
# calling sequence:
#	push number_of_ints (array_size)
#	push base_address of int array
#	call	showStats
#	add 8 to stack pointer
# ....................................................................
# author: David Bozarth - 30 April 2004
# modified 30 April 2004
# --------------------------------------------------------------------
STDIN = 0
STDOUT = 1
#
# Stack frame
stkTop = intSum		# top-of-stack marker	
intSum = -8		# calculated_sum local variable
intAvg = -4		# calculated_average local variable
basePtr = 0
rtnAddr = 4
intPtrIn = 8		# int_array_base_address argument
intSize = 12		# number_of_integers (array size) argument
	
	.data
strSum:
	.string "Sum = "
strAvg:
	.string "Average = "
strNewl:
	.string "\n"
	
	.text
	.align 4
	.globl showStats

showStats:
	pushl	%ebp			# save caller's base pointer
	movl	%esp, %ebp		# establish our base pointer
	addl	$stkTop, %esp		# allocate local variables
	pushl	%ebx			# save registers
	pushl	%ecx
	pushl	%edx
	#movl	$0, intCount(%ebp)	# initialize local variable(s)

	# find the sum
	movl	intSize(%ebp), %ecx	# array size (n_ints)
	pushl	%ecx
	movl	intPtrIn(%ebp), %ebx	# array base address
	pushl	%ebx
	call	sumList			# sum -> eax
	addl	$8, %esp
	movl	%eax, intSum(%ebp)	# store sum locally

	# find the average
	#xorl	%edx, %edx		# clear upper dividend register
	#divl	intSize(%ebp)		# sum / n
	pushl	intSize(%ebp)		# push divisor
	
	#cmpl	$0, %eax		# if sum is negative
	movl	$0x80000000, %ecx
	andl	%eax, %ecx
	cmpl	$0, %ecx		# if sum is negative
	je	notNeg			# .. then extend the sign

	negl	%eax
	pushl	%eax			# lo word
	pushl	$-1			# hi word
	jmp	doneNeg
	
notNeg:	
	pushl	%eax			# lo word
	pushl	$0
doneNeg:
	call	divInt
	addl	$12, %esp
	movl	%eax, intAvg(%ebp)	# store quotient locally
	
	# display stats
	pushl	$strNewl		# send newline to display	
	call	writeStr
	addl	$4, %esp
	pushl	$strSum			# display sum
	call	writeStr
	addl	$4, %esp
	pushl	intSum(%ebp)
	call	putDec
	addl	$4, %esp
	pushl	$strNewl		# send newline to display	
	call	writeStr
	addl	$4, %esp
	pushl	$strAvg			# display average
	call	writeStr
	addl	$4, %esp
	pushl	intAvg(%ebp)
	call	putDec
	addl	$4, %esp
	pushl	$strNewl		# send newline to display	
	call	writeStr
	addl	$4, %esp

allDone:
	#movl	%ecx, %eax		# return number of ints displayed
	popl	%edx			# restore registers
	popl	%ecx			# restore registers
	popl	%ebx
	movl	%ebp, %esp		# restore stack pointer
	popl	%ebp			# restore caller's base pointer
	ret
