Download presentation
Presentation is loading. Please wait.
Published byBrenda Webb Modified over 6 years ago
1
Function Calls in MIPS To call a function: jal func
jal has a side-effect: it sets $ra to address of instruction after jal To return from a function: jr $ra Calling conventions: arguments “passed” in registers $a0, …, $a3 return values in registers $v0, $v1 callee can destroy: $t0-$t9 $a0-$a3 $v0-$v1 callee assumes caller will need: $s0-$s7 $ra For MP 2: You will be writing a function (called from our main program), which also calls one of our functions you must assume the worst!
2
Example C++ code fragment: if(func(7) == 7)
# free to modify $a, $t and $v registers jr $ra main: li $a0, 7 # set argument for call to func jal func # call func(7) bne $a0, $v0, else # test if func(7) == 7 Since we want to preserve $a0 across the function call, we must save it before the call, and then restore it after the call. MIPS stack grows downwards, $sp points to “top” 0x7FFFFFFF 0x $sp stack
3
Pushing elements To push elements onto the stack:
“Grow stack” by subtracting from $sp Store the elements into the stack (array) Example: Push $t1 and $t2 onto stack addi $sp, $sp, -8 sw $t1, 0($sp) sw $t2, 4($sp) Returning to our previous example: li $a0, 7 addi $sp, $sp, -4 sw $a0, 0($sp) jal func # restore $a0 bne $a0, $v0, else Before word 2 word 1 $sp word 2 word 1 $sp After $t2 $t1
4
Accessing and popping elements
You can access any element in the stack (not just the top one) if you know where it is relative to $sp For example, to retrieve the value of $t2: lw $t2, 4($sp) You can pop, or “erase,” elements simply by adjusting the stack pointer upwards Example: addi $sp, $sp, 4 Note: The “popped” data is still present in memory, but data past the stack pointer is considered invalid word 2 word 1 $sp $t2 $t1 word 2 word 1 $sp $t2 $t1
5
Finishing the main example
func: # free to modify $a, $t and $v registers jr $ra main: li $a0, # set argument for call to func addi $sp, $sp, -4 # grow stack sw $a0, 0($sp) # save $a0 on stack jal func # call func(7) lw $a0, 0($sp) # restore $a0 from stack addi $sp, $sp, 4 # shrink stack bne $a0, $v0, else ... jr $ra Unfortunately, main won’t return correctly! Any time you do a jal, you must save and restore $ra
6
Translate into MIPS int plusOne(int x) { return x + 1; } void main() {
x += plusOne(x); plusOne: # a0 = x addi $v0, $a0, 1 jr $ra main: li $a0, 5 addi $sp, $sp, -8 sw $ra, 0($sp) sw $a0, 4($sp) jal plusOne lw $ra, 0($sp) lw $a0, 4($sp) addi $sp, $sp, 8 add $a0, $a0, $v0
7
Recursive Functions Recall that recursive functions have one or more base-cases, and one or more recursive calls. Example: int rec_max(int *array, int n) { if(n == 1) return array[0]; return max(array[n-1], rec_max(array, n-1)); } Useful tip: Translate the base case first (rarely needs the stack) rec_max: # $a0 = array = &array[0], $a1 = n bne $a1, 1, rec_case lw $v0, 0($a0) # return-value = array[0] jr $ra rec_case: ...
8
The Recursive Case Let’s examine the recursive step more carefully:
return max(array[n-1], rec_max(array, n-1)); Useful tip: Figure out what we need to remember across the recursive function call: array[n-1] ($a0 = array, $a1 = n) rec_case: addi $sp, $sp, -12 # save space for 3 regs addi $a1, $a1, -1 # compute n-1 sw $a0, 0($sp) # save &array[0] sw $a1, 4($sp) # save n-1 sw $ra, 8($sp) # save $ra, since I’m doing jal! jal rec_max # recursive call w/new args # restore $a0, $a1 and $ra # compare array[n-1] and $v0, and put larger into $v0
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.