1 / 8

Function Calls in MIPS

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

janicediaz
Download Presentation

Function Calls in MIPS

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Function Calls in MIPS • To call a function: jalfunc • 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. 0x7FFFFFFF stack $sp 0x00000000 Example • C++ code fragment: if(func(7) == 7) func: # 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”

  3. word 1 $sp word 2 Before word 1 word 2 $sp After 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 $t2 $t1

  4. word 1 word 2 $t2 $sp $t1 word 1 word 2 $sp $t2 $t1 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

  5. Finishing the main example func: # free to modify $a, $t and $v registers jr $ra main: li $a0, 7 # 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() { int x = 5; 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 jr $ra

  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

More Related