# -------------------------------------------------------------------
# uDecToInt.s
#	convert decimal string to unsigned integer
# Takes the address of a C-style text string.
# Assumes the string contains only decimal numerals.
# Assumes the represented integer does not exceed 32 bits of storage.
# Converts the string & returns the corresponding unsigned int.
# ...................................................................
# calling sequence:
#	push address of string to be converted
#	call	uDecToInt
#	add 4 to stack pointer
# ...................................................................
# author: David Bozarth - 21 April 2004
# modified 25 April 2004
# -------------------------------------------------------------------
#
# Stack frame
stkTop = -12
intCount = -12  # number of characters converted
intUnx = -8	# place to build unsigned int
strLoc = -4	# local string address variable
basePtr = 0
rtnAddr = 4
strIn = 8	# string address passed as argument

	.data
byTen:
	.long	10			# decimal multiplier
msgOflo:
	.string "Error:	unsigned integer overflow.\n"

	.text
	.align 4
	.globl uDecToInt

uDecToInt:
	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	strIn(%ebp), %eax	# initialize local variables
	movl	%eax, strLoc(%ebp)
	movl	$0, intCount(%ebp)
	movl	$0, intUnx(%ebp)
	
convertLoop:
	movl	strLoc(%ebp), %ebx	# address of next char in string
	cmpb	$0, (%ebx)		# test for null terminator
	je	allDone

	movl	intUnx(%ebp), %eax	# load multiplicand	
	mull	byTen			# take product
	cmpl	$0, %edx		# if overflow is detected
	jne	errOflo			# .. display advisory & exit

	movb	(%ebx), %cl		# load byte holder
	andl	$0x0f, %ecx		# convert decimal digit to 4-bit value
	addl	%ecx, %eax		# insert new 4-bits to accumulator
	movl	%eax, intUnx(%ebp)	# update stack variable
	incl	strLoc(%ebp)		# increment pointer
	incl	intCount(%ebp)		# increment character count
	jmp	convertLoop

errOflo:
	pushl	$msgOflo		# inform user of Overflow condition
	call	writeStr
	addl	$4, %esp
	
allDone:
	movl	intUnx(%ebp), %eax	# return unsigned int result
	popl	%edx			# restore registers
	popl	%ecx
	popl	%ebx
	movl	%ebp, %esp		# restore stack pointer
	popl	%ebp			# restore caller's base pointer
	ret
