.macro lstr %rd, %str
	.data
	lstr_message: .asciiz %str
	.text
	la %rd, lstr_message
.end_macro

.macro print_str %str
	push a0
	push v0
	lstr a0, %str
	li v0, 4
	syscall
	pop v0
	pop a0
.end_macro

# --------------------------------------------------
.global main
main:
	# try changing these arguments.

	# print_min_of(12, 28)
	li a0, 12
	li a1, 28
	jal print_min_of

	# exit
	li v0, 10
	syscall

# --------------------------------------------------
# int min(int a, int b)

# returns the smaller of a and b.
# since it takes 2 arguments, by the calling convention
# they must be passed in a0 and a1, so the code is written
# to assume that.
# the return value is whatever is in v0 when the
# function returns.
min:
	push ra # technically not needed since no jal,
	# but let's not rely on "technically", okay?

	# just 4 lines, very simple, but think about how it
	# works (and step through it if you need to).
	move v0, a0
	ble a0, a1, _endif
		move v0, a1
	_endif:

	pop ra
	jr ra

# --------------------------------------------------
# void print_min_of(int a, int b)
#
# prints the minimum of a and b in a nice way.
# also demonstrates a function which needs s regs
# to do its job.
print_min_of:
	push ra
	push s0
	push s1

	# since we are printing out the two arguments,
	# and then passing them into another function later,
	# we can't just keep them in a0 and a1 or they'll
	# get overwritten. so, we are forced to keep these
	# values in s registers so they're safe for later.

	# from now on,
	#    s0 = a
	#    s1 = b
	move s0, a0
	move s1, a1 # technically you could write this function without saving a1, but
	# let's not rely on "technically", okay?

	# man, printing things in asm is a pain, huh?
	print_str "min("

	# print_int(a)
	move a0, s0 # technically not needed, but let's not rely on "technically", okay?
	li v0, 1
	syscall

	print_str ", "

	# print_int(b)
	move a0, s1 # this is the line that would have overwritten the value of a, and it's
				# why we needed to save its value in an s reg.
	li v0, 1
	syscall

	print_str ") = "

	# print_int(min(a, b))
	move a0, s0
	move a1, s1
	jal min
	move a0, v0
	li v0, 1
	syscall

	print_str "\n"

	# !!!!!!!!!!! NOTICE!!!!!!!!!!!!!!!!!
	# the pops are in the *reverse order*
	# of the pushes. because it's a stack.
	pop s1
	pop s0
	pop ra
	jr ra