200 likes | 401 Views
MAL 3 - Procedures. Lecture 13. MAL procedure call. The use of procedures facilitates modular programming. Four steps to transfer to and return from a procedure: save return address procedure call execute the procedure return. SAL. MAL. la addvar, rtnadd b proc1 rtnadd:
E N D
MAL 3 - Procedures Lecture 13
MAL procedure call • The use of procedures facilitates modular programming. • Four steps to transfer to and return from a procedure: • save return address • procedure call • execute the procedure • return
SAL MAL la addvar, rtnadd b proc1 rtnadd: . . . proc1: . . . b (addvar) jal proc1 . . . proc1: . . . jr $31 Automatically loads the contents of $31 to PC(program counter) Automatically loads the address of the instruction followingjal proc1 to $31(also called $ra) and branches to proc1
Dynamic Storage Allocation • To handle procedure calls from within a procedure it is no longer adequate to only use a register to store the return addresses. • The return addresses can be stored in a dynamically allocated storage implemented as a stack. This stack is called the system stack. • The stack pointer can be accessed using $sp or $29. $sp points to the first available space.
small memory addresses $sp bottom large memory addresses 1 word
System Stack Operations push sw $8,0($sp) add $sp,$sp,-4 add $sp,$sp,-4 sw $8,4($sp) pop add $sp,$sp,4 lw $8,0($sp) lw $8,4($sp) add $sp,$sp,4
base power execute: power(2,2) Example 13.1 $sp 16 execute: power(2,3)? $sp 40 16
Example 13.2 Power(2,3) 2*4=8 leaf Power(2,2) 2*2=4 Power(2,1) 2*1=2
Activation Records • When a procedure is invoked, a new environment is created. New local variables maybe defined and values of other variables, e.g. parameters, maybe carried over from the previous environment. • The previous environment before the call must be saved in a stack and restored when the call is terminated. • The new environment will cease to exist when the call is terminated thus memory space where these values are to be saved are allocated dynamically.
The collection of all the information corresponding to a state of a procedure is called an activation record. • An activation record is pushed onto the stack like words (as we did in Example 21.2) except it is larger than a word and variable in size. • A return address is just one component of an activation record.
Parameter Passing • In general, passing parameters in registers alone will not work for programs that contain nested procedure calls. • There are only a limited number of registers and potentially many nested calls, thus registers have to be reused. During reuse, values of variables that may belong to a previous environment will get overwritten. • A safe way to pass parameters when there are nested calls is to use a stack.
Allocation of space for parameters can be done by a sequence of pushes onto a stack. • Each parameter is pushed onto the stack one at a time. • The calling program pushes the parameters onto the stack and transfers control to the called procedure. The called procedure then saves the return address by pushing it onto the stack.
parameter2 parameter2 parameter1 parameter1 Example 13.3 return add stack pointer
Example 13.4 add $sp,$sp,-16 sw $8,16($sp) sw $12,12($sp) sw $6,8($sp) jal proc . . . proc: sw $31,4($sp) Parameters are in $8,$12,$6 respectively. Here the entire activation record is pushed in one group and so the stack pointer is adjusted only once. Parameters may also be pushed one at a time. In this case, the stack pointer is adjusted more than once.
Returning results & parameter types • Most programming languages return only a single value from a procedure call. A common practice is to save the return value in a register. • In a pass-by-reference, an address is passed to the called procedure. The called procedure can then modify the value of the variable. • In a pass-by-value, only the value of the variable is passed as a parameter, thus no modification can be done to the original values.
Saving Registers • Registers can be reused by the called procedures provided that the state of the environment before procedure execution is saved. • These information are again saved using a stack and restored to original values when the called procedure terminates. • When is saving performed? • Called procedure does it • Calling procedure saves them before the call
The called procedure can push onto the stack the values of the registers it will be using. • This clears enough registers to be used by the called procedure. Restoration is performed just before it returns. • The calling procedure can also push onto the stack the values of registers it does not want changed by the called procedure. This can be done as part of the setup for a procedure call.
calling procedure setup Example 13.5 called procedure setup jal proc . . . proc: sw $ra,0($sp) add $sp,$sp,-4 add $sp,$sp,-12 sw $t0,12($sp) sw $t1,8($sp) sw $t2,4($sp) …#proc code here lw $t2,4($sp) lw $t1,8($sp) lw $t0,12($sp) add $sp,$sp,12 add $sp,$sp,4 lw $ra,0($sp) jr $ra add $sp,$sp,-12 sw $t0,12($sp) sw $t1,8($sp) sw $t2,4($sp) jal proc lw $t2,4($sp) lw $t1,8($sp) lw $t0,12($sp) add $sp,$sp,12 . . . proc: sw $ra,0($sp) add $sp,$sp,-4 …#proc code here add $sp,$sp,4 lw $ra,0($sp) jr $ra
The return address can be saved like any other register but it must saved after the procedure call. • This is so because only after a procedure call that $31 will contain the return address. • In MIPS RISC architecture the first four parameters are passed via $4,$5,$6,$7. Additional parameters are passed via the stack. • If parameters are passed via $4 and $5, the procedure must first save them before calling another procedure.
Some conventions $1 - reserved by the assembler $2-$3 - expression evaluation $4-$7 - first four parameters $8-$15 - temporaries $16-$23 - saved across procedure calls $26-$27 - reserved for operating system $f20-$f30 - saved across procedure calls For a more extensive example, check pp. 245-251 of the text.