//-----------------------------------------------------------------
//	demo2.s
//
//	This is the same computation as in 'demo0.py', but written
//	with the GNU/Linux assembly language for an x86 processor. 
//
//	    assemble with:  $ as demo2.s -o demo2.o
//	    and link with:  $ ld demo2.o sprintf.o -o demo2
//	    execute using:  $ ./demo2
//
//	programmer: ALLAN CRUSE
//	written on: 02 JAN 2009
//-----------------------------------------------------------------

	.equ	dev_STDOUT, 1	# mnemonic for output device-file
	.equ	sys_WRITE, 1	# mnemonic for kernel service #1
	.equ	sys_EXIT, 60	# mnemonic for kernel service #60

	.section	.data
x:	.quad	4			# integer variable: x=4
y:	.quad	5			# integer variable: y=5
fmt:	.asciz	"%d + %d = %d \n"	# to specify formatting

	.section	.bss
z:	.quad	0			# integer variable: z=?
n:	.quad	0			# integer variable: n=?
buf:	.space	80			# to store output chars

	.section	.text
_start:	
	# perform the assignment: z = x + y
	mov	x, %rax		# puts x in register RAX
	add	y, %rax		# adds y to value in RAX
	mov	%rax, z		# save sum at location z

	# call library-function: len = sprintf( buf, fmy, x, y, z );
	push	z		# push argument #5 onto stack
	push	y		# push argument #4 onto stack
	push	x		# push argument #3 onto stack
	push	$fmt		# push argument #2 onto stack
	push	$buf		# push argument $1 onto stack
	call	sprintf		# perform 'external' function
	add	$40, %rsp	# discards the five arguments
	mov	%rax, n		# save RAX as our value for n

	# make Linux system-call: write( dev_STDOUT, &buf, len );
	mov	$sys_WRITE, %rax	# service-ID into RAX
	mov	$dev_STDOUT, %rdi	# device_ID into EDI
	mov	$buf, %rsi		# buffer address in RSI
	mov	n, %rdx			# string length in EDX
	syscall				# transfer to OS kernel

	# make Linux system-call: exit( 0 );
	mov	$sys_EXIT, %rax		# service-id into RAX
	mov	$0, %rdi		# return-code into RDI
	syscall				# transfer to OS kernel

	.global	_start		# tells linker our entry-point
	.end			# tells assembler to stop here