Upload
clarissa-claudia-etchells
View
405
Download
13
Tags:
Embed Size (px)
Citation preview
Chapter 2
Supporting Procedures in Computer Hardware
(Instructions: Language of the Computer
Part VI)
Procedures/Functions Stored subroutine that performs a specific
task based on parameters with which it is provided
Use to structure programs – readability and reuse
C++ Functions
main()
{int i,j,k,m;...i = mult(j,k); ... m = mult(i,i); ...
}
What information must compiler/ programmer keep track of?
What instructions can accomplish this?
/* simple mult function */
int mult (int m, int n)
{int product = 0;while (m > 0)
{ product = product + n; m = m -1;
}return product;
}
Functions Leaf functions do not call other functions
Nonleaf functions invoke other functions or themselves (reucursive)
We will be learning only about leaf functions
Procedure Execution1. Calling procedure places parameters in registers
where the callee procedure can access them.
2. Calling procedure transfers control to the callee procedure (jal instruction)
3. Callee procedure acquires the storage resources needed for the procedure (registers)
4. Callee procedure performs the desired task (execute the procedure)
5. Callee procedure places the result(s) in register(s) where the calling procedure can access it
6. Callee procedure returns control to the calling procedure at the point of call origin
Florida A & M University - Department of Computer and Information Sciences
Procedure Calling (Brief) Steps required
1. Place actual arguments in registers
2. Transfer control to procedure
3. Acquire storage for procedure
4. Perform procedure’s operations
5. Place result in register for caller
6. Return to place after site of call
Florida A & M University - Department of Computer and Information Sciences
Register Usage Arguments : $a0 – $a3 Return values: $v0, $v1 Temporary: $t0 – $t9
Can be overwritten by callee
Local variables : $s0 – $s7 Must be saved/restored by callee
$gp - global pointer for static data $sp - stack pointer : $sp $fp - frame pointer : $fp $ra - return address : $ra
Instruction Support for Functions
... sum(a,b);... /* a,b:$s0,$s1 */}int sum(int x, int y) {
return x+y;}
address1000 1004 1008 1012 1016
2000 2004
C++
MIPS
In MIPS, all instructions are 4 bytes, and stored in memory just like data. So here we show the addresses of where the programs are stored.
Instruction Support for Functions ... sum(a,b);... /* a:$s0; b:$s1 */
}int sum(int x, int y) {
return x+y;}
address1000 move $a0, $s0 # x = a1004 move $a1, $s1 # y = b 1008 need instruction to call a procedure and save
the return address 1012 1016 ...
2000 sum: add $v0,$a0,$a12004 need an instruction to jump back to the saved
address
Florida A & M University - Department of Computer and Information Sciences
Procedure Call Instructions Procedure return: jump register
jr $ra
Instead of providing a label to jump to, this instruction provides a register which contains an address to jump to.
PC $ra
Can also be used for computed jumps e.g., for case/switch statements
Florida A & M University - Department of Computer and Information Sciences
Procedure Call Instructions Procedure call: jump and link
jal ProcedureLabel
Address of following instruction put in $ra Jumps to target address Why have a jal?
Make the common case fast No need to know where the code is loaded into
memory with jal.
Instruction Support for Functions
... sum(a,b);... /* a,b:$s0,$s1 */}int sum(int x, int y) {
return x+y;}
address1000 move $a0, $s0 # x = a1004 move $a1, $s1 # y = b 1008 jal sum # $ra = 1012 and jump to sum
1012
1016 ...
2000 sum: add $v0,$a0,$a12004 jr $ra # jump to address in $ra
Florida A & M University - Department of Computer and Information Sciences
Memory Layout Text: program code
Static data: global variables static variables in C, constant
arrays and strings $gp initialized to address
allowing ±offsets into this segment
Dynamic data: heap malloc in C, new in C++/Java
Stack: automatic storage
Florida A & M University - Department of Computer and Information Sciences
Local Data on the Stack
Local data allocated by callee e.g., C automatic variables
Procedure frame (activation record) Used by some compilers to manage stack storage
Stack Register $sp points to the top of the stack
(i.e. the last used space in the stack)
Stack grows from high address to low address when you add an element to the stack,
subtract 4 from $sp ( addi and sw) when you delete an element from the top of
the stack, add 4 to $sp (lw and addi)
Procedure Execution StepsCalling Procedure (aka Caller) :
1. Actual arguments registers $a0 - $a32. jal ProcLabel
Callee Procedure:1. If any saved register ($s0 - $s7) is used by the callee, save
these registers on the stack (may also need to store temporary registers if they are used by callee and the caller)
2. Perform the desired task (execute the procedure)
3. Place the result in registers $v0 - $v1
4. Restore the old values of the saved registers ($s0 - $s7) from the stack
5. Return control to the beyond the origin of the call using jr instruction
Remember: Callee Procedure Rules
Called with a jal instruction, returns with a jr $ra
Accepts up to four arguments in $a0, $a1, $a2 and $a3
Return value is always in $v0 (and if necessary in $v1)
Must follow register conventions
MIPS Registers The constant 0 $0 $zero
Reserved for Assembler $1 $atReturn Values $2-$3 $v0-$v1Arguments $4-$7 $a0-$a3Temporary $8-$15 $t0-$t7Saved $16-$23 $s0-$s7More Temporary $24-$25 $t8-$t9Used by Kernel $26-27 $k0-$k1Global Pointer $28 $gpStack Pointer $29 $spFrame Pointer $30 $fpReturn Address $31 $ra
MIPS Registers $at: may be used by the assembler at any
time; unsafe to use
$k0-$k1: may be used by the OS at any time; unsafe to use
$gp, $fp: don’t worry about them Note: Feel free to read up on $gp and $fp, but
you can write perfectly good MIPS code without them.
Register Convention A set of generally accepted rules as to which
registers will be unchanged after a procedure call (jal) and which may be changed.
When callee returns from executing, the caller needs to know which registers may have changed and which are guaranteed to be unchanged.
Register Conventions - saved $0: No Change. Always 0. $s0-$s7: Restore if you change. Very important,
that’s why they’re called saved registers. If the callee changes these in any way, it must restore the original values before returning.
$sp: Restore if you change. The stack pointer must point to the same place before and after the jal call, or else the caller won’t be able to restore values from the stack.
HINT -- All saved registers start with S!
Register Conventions - violatile $v0-$v1: Can Change. These are expected to
contain new values computed by callee
$a0-$a3: Can change. These are volatile argument registers. Caller needs to save if they’ll need them after the call.
$t0-$t9: Can change. That’s why they’re called temporary: any procedure may change them at any time. Caller needs to save if they’ll need them afterwards.
$ra: Can Change. The jal call itself will change this register. Caller needs to save on stack if nested call.
Register Conventions Caller/Callee need to save only temporary/saved
registers they are using, not all registers. Caller
save any temporary registers, that it would like to preserve through the call, onto the stack before making a jal call
Callee save any S (saved) registers it intends to use
before garbling up their values
Caller MIPS Structure Copy the values of all the actual arguments into
the formal arguments ($a0 - $a3)
Save temporary registers onto stack, if necessary
Call the callee using jal instruction
Copy the results from the value registers ($v0-$v1)
Restore the temporary registers from the stack, if necessary
Callee MIPS structure Save the saved registers ($s0 - $s7) onto a
stack, if necessary
Code for the body of the function
Place the results in the value registers ($v0 - $v1)
Restore the saved registers ($s0 - $s7) from the stack, if necessary
Return to the point of call using jr $ra instruction
Examplemain() { int i, j, k, m; // i, j, k, m : $s0, $s1, $s2, $s3 i = mult(j, k); ... ; m = mult(i, i); ... }
int mult (int mcand, int mlier) { int product;
product = 0; while (mlier> 0) { product += mcand; mlier -= 1; } return product;}
Example: Register Allocation main (caller)
i : $s0 j : $s1 k : $s2 m: $s3
mult (callee) mcand : $a0 mlier : $a1 product : $v0
Example: Callermain() { int i, j, k, m; // i, j, k, m : $s0, $s1, $s2, $s3 i = mult(j, k); ... ; m = mult(i, i); ... }int mult (int mcand, int mlier) { ……………………………… return product;} Copy the values of all the actual arguments j ($s1) and k ($s2) into
the formal arguments mcand($a0) and mlier($a1) Call the callee using jal instruction Copy the results from the value registers product ($v0) into i ($s0)
Example: Caller MIPSmain:
add $a0, $s1, $zero # arg0 = jadd $a1, $s2, $zero # arg1 = k jal mult # call multadd $s0, $v0, $zero # i = mult()
add $a0, $s0, $zero # arg0 = iadd $a1, $s0, $zero # arg1 = i jal mult # call multadd $s3, $v0, $zero # m = mult()
done:
Example: Caller Notes:
all variables used are saved registers ($s0 - $s3), no need to store any temporary onto stack
mult does not have to save any of the saved registers ($s0 - $s3) as it does not use any of these saved registers. The only registers used by mult are $a0, $a1, $v0
Example: Calleeint mult (int mcand, int mlier) { int product;
product = 0; while (mlier > 0) { product += mcand; mlier -= 1; } return product;}
Save all the saved registers only if they are used by the caller and the callee onto a stack
None; do not have to save on the stack
Code for the body of the function
Example: Calleeint mult (int mcand, int mlier) { int product;
product = 0; while (mlier> 0) { product += mcand; mlier -= 1; } return product;}
Place the results in the value registers ($v0) Restore the saved registers from the stack
None; do not have to restore saved registers from the stack Return to the point of call using jr $ra instruction
Example: Callee MIPSmult:
add $t0, $0, $0 # prod=0Loop:
slt $t1,$0,$a1 # mlier > 0? beq $t1, $0, Fin # no => Finadd $t0, $t0, $a0 # prod += mcaddi $a1, $a1, -1 # mlier -= 1j Loop # goto Loop
Fin:add $v0, $t0, $0 # $v0=prod jr $ra # return
Example: Callee MIPS Notes:
no jal calls are made from mult and we don’t use any saved registers, so we don’t need to save anything onto stack
temp registers are used for intermediate calculations (could have used s registers, but would have to save the caller’s on the stack.)
$a1 is modified directly (instead of copying into a temp register) since we are free to change it
result is put into $v0 before returning
Example2:main() { int a, b, c, d, e;
e = leaf_example (a, b, c, d); }
int leaf_example (int g, int h, int i, int j) { int f;
f = (g + h) – (i + j); return f;}
Example2: Register Allocation
main (caller)
a b c d e $s0 $s1 $s2 $s3 $s4
leaf_example (callee)
g h i j f $a0 $a1 $a2 $a3 $s0
Example2: Caller MIPSmain:
add $a0, $s0, $zero # copy a to g
add $a1, $s1, $zero # copy b to h
add $a2, $s2, $zero # copy c to i
add $a3, $s3, $zero # copy d to j
jal leaf_example # call leaf_example
add $s4, $v0, $zero # copy result to e
Example2: Callee MIPSleaf_example:
addi $sp, $sp, -4 # adjust the stack for one # item
sw $s0, 0($sp) #save $s0
add $t0,$a0,$a1 # temp0 = g + hadd $t1,$a2,$a3 # temp1 = i + jsub $s0,$to,$t1 # f = temp0 – temp1add $v0,$s0,$zero # $v0 = f
lw $s0, 0 ($sp)addi $sp, $sp, 4
jr $ra # return
Example2: Note:
The sections for adjusting the stack are different from the book as there is no need to save the temporary registers.
More than 4 arguments Actual argument values are spilled into
memory and these memory locations correspond to the formal arguments
Will slow down your program
Ideal: Functions should be kept very small with a limited number of arguments
Things to Remember
Function is called with jal funcLabel
Function returns with jr $ra.
The stack is your friend: Use it to save anything you need. Just be sure to leave it the way you found it.
Register usage conventions: understand the purpose and limits on register usage in functions you’re writing all the code yourself.