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 |