;;; This program prompts for and reads three integers, then prints the
;;; maximim of the three.  Demonstrates calling and stack manipulation
;;; including calling two internal functions.
        global  main
        extern  printf
        extern  scanf

        section .text

	;; Read the first two inputs, and push them on the stack.
	;; Note: We use a dirty trick (three times!) of moving a value to
	;; the stacktop instead of discarding the top, then pushing a value.
main:	push	p1
	call	req
	mov	[esp],eax	; Replace prompt on stacktop with result

	push	p2
	call	req
	mov	[esp],eax	; Now, the first two nums are on the stack.

	;; Find the larger of the two inputs.  Parms already on the stack
	call	max
	add	esp,8		; Lose the two args
	push	eax		; Put the max there.

	;; Ask the other input and get it on the stack
	push	p3
	call	req
	mov	[esp],eax	; Now the previous max and new number on top.

	;; Get the max (in EAX)
	call	max
	add	esp,8

	;;  Print the result
	push	eax
	push	mfmt
	call	printf
	add	esp,8

	;; All done
	ret

	section	.data
	;; Three prompts, and the max message.
p1:	db	'Please enter the first integer',0
p2:	db	'How about another one',0
p3:	db	'And one more, just for fun',0
mfmt:	db	'The largest one is %d.',10,0

	section .text
; Return the maximum of two integers.
max:	mov	eax, [esp+4]	; Load first arg
	cmp	eax, [esp+8]	; Compare to the second argument
	jg	noch		; If it's already the max don't change it.
	mov	eax, [esp+8]	; Change it.

; Wrap it up.  Leaves the max in eax, which is the return.
noch:	ret

; Request and return an integer.  Argument is a prompt string.
req:	push	ebp		; Set up the frame ptr
	mov	ebp, esp

	sub	esp, 4		; Make some room for a temp variable

	;; Make the prompt.
	push	dword [ebp+8]	; Push argument (string) as arg to printf.
	push	strfmt		; Push the format as arg to printf.
	call	printf
	add	esp,8		; Remove args from stack.

	;; Read the value
	lea	eax,[ebp-4]	; Address of the temp variable on the stack.
	push	eax		; Put it on the stack
	push	rdfmt		; Reading format.
	call	scanf
	add	esp,8		; Remove from stack.

	;; Make the read value the return value
	mov	eax,[ebp-4]

	;; Clean up
	add	esp, 4
	mov	esp, ebp
	pop	ebp
	ret

	section	.data
strfmt:	db	'%s: ',0	; Printf format for printing the promt.
rdfmt:	db	'%d',0		; Scanf format for reading an integer value.

