# -------------------------------------------------------------------
# sDecToInt.s
#	convert decimal string to signed integer
# Takes the address of a C-style text string.
# The first character may be either '+', '-', or a decimal numeral.
# (Leading '+' is allowed but not required for a nonnegative integer.)
# Following the first character, the string has only decimal numerals.
# Assumes the represented integer does not exceed 32 bits of storage.
# Converts the string & returns the corresponding signed int.
# ...................................................................
# calling sequence:
#	push address of source string
#	call	sDecToInt	
#	add 4 to stack pointer
# ...................................................................
# author: David Bozarth - 25 April 2004
# modified 25 April 2004
# -------------------------------------------------------------------
#
# Stack frame
stkTop = -12	# top-of-stack marker
intBuild = -12	# construction zone for return value
blnIsNeg = -8	# if nonzero then int is negative, else non-negative
strLoc = -4	# local string address variable
basePtr = 0
rtnAddr = 4
strIn = 8	# string address passed as argument
	
	.text
	.align 4
	.globl sDecToInt

sDecToInt:
	pushl	%ebp			# save caller's base pointer
	movl	%esp, %ebp		# establish our base pointer
	addl	$stkTop, %esp		# allocate local variables
	pushl	%ebx			# save registers - using write()

	movl	strIn(%ebp), %ebx	# initialize local variables
	movl	%ebx, strLoc(%ebp)
	movl	$0, intBuild(%ebp)
	movl	$0, blnIsNeg(%ebp)
	
	# inspect first char for sign .. (ebx contains string address)
	cmpb	$'-', (%ebx)		# detect 'minus-sign' in first position
	jne	notMinus
	movl	$-1, blnIsNeg(%ebp)	# set 'negative integer' flag
	jmp	doneMinus
notMinus:
	cmpb	$'+', (%ebx)		# detect 'plus-sign' in first position
	jne	doConvert
doneMinus:
	incl	%ebx			# advance char pointer	
	movl	%ebx, strLoc(%ebp)	# .. & update local variable
doConvert:	
	pushl	%ebx			# convert string to integer
	call	uDecToInt		# (callee returns int in eax)
	addl	$4, %esp
	cmpl	$0, blnIsNeg(%ebp)	# handle negation
	je	allDone
	negl	%eax			

allDone:
	popl	%ebx			# restore register
	movl	%ebp, %esp		# restore stack pointer
	popl	%ebp			# restore caller's base pointer
	ret
