# Procedure Calls and the Stack

### Function A

 int A(int a, int * b, int C[]) { if (a == C[2]) *b = a * 2; a = a - *b; return a; } A: lw \$t0, 8(\$a2) bne \$a0, \$t0, ENDIF sll \$t1, \$a0, 1 sw \$t1, 0(\$a1) ENDIF: sub \$a0, \$a0, \$t1 add \$v0, \$a0, \$zero jr \$ra # \$a0 = a, \$a1 = b, \$a2 = C # save anything to stack? # read C[2] into \$t0 # if (a != C[2]) goto ENDIF # \$t1 = a * 2; # store \$t1 to address b (*b = \$t1) # a = a - *b; # store a in \$ra for return a # restore anything from stack? # return to address in \$ra

### In A, do we need to store anything on the Stack?

Function A is a leaf function, and we decided to use only \$t registers, so we do not need to store anything on the Stack.

### Calling function A

 int caller() { int x, y; int Z[20]; ... x = A(x, &y, Z); ... } caller(): ... move \$a0, \$s0 move \$a1, \$s1 move \$a2, \$s2 jal A move \$s0, \$v0 ... jr \$ra # int caller() # save anything to stack? #... (assume x, &y, z are in s0, s1, s2) # store x, &y, Z into \$a0, \$a1, \$a2 # jump to function named A # store return value (\$v0) in x # ... # restore anything from stack? # return to address in \$ra

### In caller, do we need to store anything on the Stack?

caller calls a function, so we need to save \$ra and \$a registers to the Stack. It is also currently using \$s0, \$s1, \$s2, so need to save them as well.

 int caller() { int x, y; int Z[20]; ... x = A(x, y, Z); ... } caller: addi \$sp, \$sp, -28 sw \$s2, 24(\$sp) sw \$s1, 20(\$sp) sw \$s0, 16(\$sp) sw \$a2, 12(\$sp) sw \$a1, 8(\$sp) sw \$a0, 4(\$sp) sw \$ra, 0(\$sp) ... move \$a0, \$s0 move \$a1, \$s1 move \$a2, \$s2 jal A move \$s0, \$v0 ... lw \$ra, 0(\$sp) lw \$a0, 4(\$sp) lw \$a1, 8(\$sp) lw \$a2, 12(\$sp) lw \$s0, 16(\$sp) lw \$s1, 20(\$sp) lw \$s2, 24(\$sp) addi \$sp, \$sp, 28 jr \$ra # adjust stack pointer # save \$ra, \$a0-a2, \$s0-s2 to stack #... (assume x, &y, z are in s0, s1, s2) # store x, &y, Z into \$a0, \$a1, \$a2 # jump to function named A # store return value (\$v0) in x #... # restore \$ra, \$a0-a2, \$s0-s2 from stack # adjust stack pointer # return to address in \$ra

### Do we need to store anything else on the Stack?

If we need to refer to &y, where is y? Where is the memory allocated for Z?
Local variables are stored on the Stack, although we can just store x in \$s0.

 int caller() { int x, y; int Z[20]; ... x = A(x, y, Z); ... } caller: addi \$sp, \$sp, -104 sw \$s0, 16(\$sp) sw \$a2, 12(\$sp) sw \$a1, 8(\$sp) sw \$a0, 4(\$sp) sw \$ra, 0(\$sp) ... move \$a0, \$s0 addi \$a1, \$sp, 20 addi \$a2, \$sp, 24 jal A move \$s0, \$v0 ... lw \$ra, 0(\$sp) lw \$a0, 4(\$sp) lw \$a1, 8(\$sp) lw \$a2, 12(\$sp) lw \$s0, 16(\$sp) addi \$sp, \$sp, 104 jr \$ra # save space for y and Z on the stack # (4 bytes + 80 bytes) # save \$s0 to stack (x) # save \$ra, \$a0-a2 to stack #... (y, z are at 20(\$sp), 24(\$sp)) # store x in \$a0 # store &y in \$a1 # store Z in \$a2 # jump to function named A # store return value (\$v0) in x #... # restore \$ra, \$a0-a2, \$s0 from stack # adjust stack pointer # return to address in \$ra