Function Calls in MIPS To call a function

  • Slides: 8
Download presentation
Function Calls in MIPS § To call a function: jal func — jal has

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 § Calling conventions: — arguments “passed” in registers $a 0, …, $a 3 — return values in registers $v 0, $v 1 — callee can destroy: $t 0 -$t 9 $a 0 -$a 3 $v 0 -$v 1 — callee assumes caller will need: $s 0 -$s 7 $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! $ra 1

Example § C++ code fragment: if(func(7) == 7) 0 x 7 FFFFFFF stack func:

Example § C++ code fragment: if(func(7) == 7) 0 x 7 FFFFFFF stack func: # free to modify $a, $t and $v registers jr $ra main: li $a 0, 7 # set argument for call to func jal func # call func(7) bne $a 0, $v 0, else # test if func(7) == 7 § Since we want to preserve $a 0 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” $sp 0 x 0000 2

Pushing elements § To push elements onto the stack: — “Grow stack” by subtracting

Pushing elements § To push elements onto the stack: — “Grow stack” by subtracting from $sp — Store the elements into the stack (array) word 1 $sp word 2 § Example: Push $t 1 and $t 2 onto stack addi $sp, -8 sw $t 1, 0($sp) sw $t 2, 4($sp) Before word 1 § Returning to our previous example: li $a 0, 7 addi $sp, -4 sw $a 0, 0($sp) jal func # restore $a 0 bne $a 0, $v 0, else word 2 $t 2 $sp $t 1 After 3

Accessing and popping elements word 1 § You can access any element in the

Accessing and popping elements word 1 § 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 $t 2: lw word 2 $t 2 $sp $t 1 $t 2, 4($sp) § You can pop, or “erase, ” elements simply by adjusting the stack pointer upwards word 1 word 2 § Example: addi $sp, 4 § Note: The “popped” data is still present in memory, but data past the stack pointer is considered invalid $sp $t 2 $t 1 4

Finishing the main example func: # free to modify $a, $t and $v registers

Finishing the main example func: # free to modify $a, $t and $v registers jr $ra main: li $a 0, 7 # set argument for call to func addi $sp, -4 # grow stack sw $a 0, 0($sp) # save $a 0 on stack jal func # call func(7) lw $a 0, 0($sp) # restore $a 0 from stack addi $sp, 4 # shrink stack bne $a 0, $v 0, else. . . jr $ra § Unfortunately, main won’t return correctly! — Any time you do a jal, you must save and restore $ra 5

Translate into MIPS int plus. One(int x) { return x + 1; } void

Translate into MIPS int plus. One(int x) { return x + 1; } void main() { int x = 5; x += plus. One(x); } plus. One: # a 0 = x addi $v 0, $a 0, 1 jr $ra main: li addi sw sw jal lw lw addi add jr $a 0, 5 $sp, -8 $ra, 0($sp) $a 0, 4($sp) plus. One $ra, 0($sp) $a 0, 4($sp) $sp, 8 $a 0, $v 0 $ra 6

Recursive Functions § Recall that recursive functions have one or more base-cases, and one

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: # $a 0 = array = &array[0], $a 1 = n bne $a 1, 1, rec_case lw $v 0, 0($a 0) # return-value = array[0] jr $ra rec_case: . . . 7

The Recursive Case § Let’s examine the recursive step more carefully: return max(array[n-1], rec_max(array,

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] ($a 0 = array, $a 1 = n) rec_case: addi $sp, -12 # save space for 3 regs addi $a 1, -1 # compute n-1 sw $a 0, 0($sp) # save &array[0] sw $a 1, 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 $a 0, $a 1 and $ra # compare array[n-1] and $v 0, and put larger into $v 0 8