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 |
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.
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 |
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 |
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 |