# Chapter 8

### The program stack and multi-level function calls

If a function calls another function, the initial return address needs to be saved; otherwise, when the second function returns, the first function won't know what address to return to as the second function overwrote the return address register (\$ra). Thus the stack is used to store the return address and any other desired data

``````
# multi-function call example; \$ra is not saved to it fails to get back
# to main (nextLine1)
main:
jal Func1   # \$ra = nextLine1
nextLine1
...
Func1:
jal Func2   # \$ra = nextLine2
nextLine2
...
jr \$ra      # \$ra = ??
Func2:
jr \$ra      # back to nextLine2
``````

The stack pointer (\$sp) register starts at 0x7ffffe00 and grows backwards (i.e. after storing 8 bytes, subtract \$sp by 8)

Multiply via recursive additions example, which uses the stack to store return addresses (\$ra) and input arguments (\$a0)

``````
.text
.globl main
main:
# register conventions
# \$s0 - m
# \$s1 - n

la \$a0, prompt1
jal PrintString
jal PromptInt
move \$s0, \$v0

la \$a0, prompt2
jal PrintString
jal PromptInt
move \$s1, \$v0

move \$a0, \$s0
move \$a1, \$s1

jal Multiply
move \$s2, \$v0

la \$a0, result
jal PrintString
move \$a0, \$s2
jal PrintInt

jal Exit

Multiply:
# Increase the stack size (grows backwards) and save the first multiply number
# and the current return address stored via the call to jal Multiply
sw \$a0, 4(\$sp)
sw \$ra, 0(\$sp)

# if our counter has reached zero, we can start doing the adds
# (skip the jal Multiply so we start adding)
seq \$t0, \$a1, \$zero
addi \$v0, \$zero, 0 	# initialize \$v0 = 0 in case we start doing the actual adds
bnez \$t0, Return

# store m-1 in m (e.g. for 2*3, \$a1 = 3,2,1,0)
# when this jump and link is called, the next line (lw) is stored in \$ra
# hence, once we get to the Return label, the stack has the lw line
# in it due to the line 'sw \$ra, 0(\$sp)' above
jal Multiply

# Do the recursive adds (\$v0 = a+a+a+a... b times)
lw \$a0, 4(\$sp)		# get the first multiply number (a in a*b)
add \$v0, \$a0, \$v0	# \$v0 = a + \$v0

Return:
lw \$ra, 0(\$sp)		# retrieve the next \$ra stored from above (points to 'Do the recursive adds')
addi \$sp, \$sp, 8	# pop the stack
jr \$ra			# go to the retrieved value

.data
prompt1: .asciiz "Enter the multiplicand: "
prompt2: .asciiz "Enter the multiplier: "
result: .ascii "The answer is: "

.include "utils.asm"
``````