Functions and Procedures
Function or Procedure A separate piece of code Possibly separately compiled Located at some address in the memory used for code, away from main and other functions (main is itself a function called by the system) May return a value to caller Function may use provided by caller
Function call Store where function can find them Store address where control should return after call Go to function code Store information in registers that need to be used by function, so they can be restored Get Execute function Put result where it can be found by caller
Function call continued Restore information in registers Return control to caller at appropriate address Caller get results
Function call -- issues How to save? How to provide for function? How to save information stored in registers? How to store return value of function so it is available to caller after function terminates
Solution 1 Use fixed location in memory for each function Nested calls of different functions can work Recursive calls, direct or mutually recursive, cannot work No longer used
Solution 2 Use a portion of memory as a stack allows recursive functions Need to keep a pointer to top of stack a register is usually used Information which can be stored on the stack (stored by caller) (stored by caller) register values needed after call (stored by caller or function) local variables for function (stored by function)
Runtime stack code memory stack memory main function 1 function 2
Runtime stack code memory stack memory main function 1 function 2 local variables return value
Runtime stack -- second call code memory main stack memory local variables function 1 function 2 return value local variables return value
Runtime stack -- red calls yellow code memory main stack memory function 1 function 2 local variables return value local variables return value local variables return value
After red - yellow call returns code memory main stack memory function 1 function 2 local variables return value local variables return value still there no longer used
After yellow- red call completes code memory main stack memory function 1 local variables still there no longer used still there no longer used function 2 return value
Solution 3 Store all values which need to be saved in registers Needs many registers Faster than using memory Eventually cannot handle recursive calls which go too deep Deep stack in registers used in Sun Sparc architecture
MIPS solution Mixed: keep as much as possible in registers Spill register contents to memory stack when needed Single function calls often use only registers Deeper function calls always use stack how much depends on register usage by functions
MIPS Register Usage ra (31) used for function sp (29) used as stack pointer v0, v1 function return value(s) a0, a1, a2, a3 function s registers guaranteed to hold same values across function calls (e.g. value after call is the same as it was before the call) t registers values may be changed by function call without being restored after
MIPS function call sequence 1. Caller places parameter values in registers $a0 - $a3 if more than four, place extra on stack 2. Caller saves values of a and t registers on stack, if needed later adjust stack pointer accordingly 3. Jump to function start address and place in register $ra jal instruction does this -- is + 4 4. Allocate memory needed for stack frame by subtracting frame size from $sp (stack pointer register). 5. Save callee-saved registers any s registers which the function will use the $ra registers if this function calls another Execute function
MIPS function call sequence - 2 11. Caller uses return value(s) which is (are) in register(s) $v0, $v1 10. Caller restores values of a and t registers from stack, if needed readjust stack pointer accordingly 9. Return to which is in $ra jr $ra instruction does this 8. Deallocate memory needed for stack frame by adding frame size to $sp (stack pointer register). 7. Restore callee-saved registers any s registers which the function used the $ra registers if this function called another 6. Place return value(s) in registers $v0-$v1