250 likes | 469 Views
Procedures Essential ingredient of high level language programs – facility to execute procedures, code sequences to perform computations that are needed repeatedly through a main program, rather than duplicate the code. (In Java procedures created with static void method).
E N D
Procedures Essential ingredient of high level language programs – facility to execute procedures, code sequences to perform computations that are needed repeatedly through a main program, rather than duplicate the code. (In Java procedures created with static void method) ITCS 3181 Logic and Computer Systems 2014 B. Wilkinson Slides4-2.ppt Modification date: March 19, 2014
In C, we might write: intmax(int a, int b) { intc; if (a > b) c = a; else c = b; return(c); } main { . z = max(x,y); . p = max(r,s); . return; } Function maxcalled in two places in the main program and returns the maximum of the two arguments (a function being a procedure that returns a value). Note main is also a procedure.
Implementing Procedures Key issues 1. A mechanism must be in place to be able to jump to the procedure from various locations in the calling program (or procedure), and to be able to return from the called procedure to the right place in the calling program (or procedure). 2. A mechanism must be place to handle the situation that a procedure may call another procedure (nested procedures) or even itself (recursive procedures) when necessary. 3. A mechanism must be in place to handle passing arguments to the procedure, and to return results (if a function). 4. The registers being used by the calling procedure must be saved, so that they can be reused by the called procedure.
1. Jumping to procedure and returning Jumping to a procedure (without considering the return) could be done by a simple jump instruction. However, the return cannot be a simple jump as each call returns to a different place, the location after the corresponding call. Necessary to store the address of this location (return address) at the time of the procedural “call”, which is then used by the return instruction.
Jump and Link Instruction Simplest solution is to use a register, say R31, to hold the return address and provide a special instruction that loads this register prior to jumping to the procedure, so-called jump and link instruction: JAL proc1 ;load return address in R31 ;and then goto proc1 Return then is simple an indirect jump: J[R31] ;goto location whose addess is ;in R31 Note: Return address is the value held in the PC counter at the time of JAL execution as PC is incremented to point to the next instruction after the current instruction has been fetched.
“return address” is the address of the instruction immediately following the procedural jump instruction, i.e. address of next instruction.
2. Nested and recursive calls Some procedures call other procedures or even call themselves. In those situations, a single register to hold the return address is insufficient, as get a series of return addresses to maintain. For that, a stack is used - – last-in-first-out queue (LIFO): Can be implemented in main memory or using registers within processor. Historically, main memory stacks have been used because they allow almost limitless nesting and recursion of procedures.
Stack Pointer A register called a stack pointerprovided inside processor to hold the address of the “top” of the stack (the end of the stack where items are loaded or retrieved). Depending upon design, stack pointer either holds address of the next free location on the stack or the address of the last item placed on the stack. Question: Any advantage of each approach? We shall assume the stack pointer holds the address of the last item placed on the stack.
As items are placed on the stack, the stack grows, and as items are removed from the stack, the stack contracts. Although not shown in figures here, normally memory stacks are made to grow downwards, i.e., items are added to locations with decreasing addresses. Why?
CALL/RET Instructions CISC machine instructions for both procedural call and procedural return. CALL proc1 – unconditional jump to start of procedure, with added feature that the return address( address of instruction after call) put on the stack. Stack pointer adjusted accordingly (decremented). RET – return to calling program after execution of procedure. An unconditional jump to location having address given by return address as found on top of stack. Stack pointer adjusted accordingly (incremented).
Suppose 32-bit addresses are stored on the stack. Then 4 bytes needed for each address, and stack pointer decremented by four each time an address is added to stack, and incremented by four as addresses are removed from stack. Part of CALL instruction is to decrement the stack pointer by 4. Part of RET instruction is to increment stack pointer by 4.
Procedure Call Before Call Stack Main program Stack pointer Top of Stack Procedure Proc1 Here Call Proc1 Next instruction Ret
Procedure Call After Call Stack Main program Stack pointer Top of Stack Return address -4 Procedure Proc1 Here Call Proc1 Next instruction Ret Return address is the address of the instruction after the Call instruction.
Procedure Call After Return Stack Main program Stack pointer Return address Top of Stack +4 Procedure Proc1 Call Proc1 Here Next instruction Ret Return address is the address of the instruction after the Call instruction.
Nested Procedure Calls Stack provides storage for each return address for nested/recursive calls.
Using JAL instruction with a stack RISCs (Reduced Instruction Set Computers) usually do not provide complex CALL and RETinstructions.Instead, they rely on using JALinstruction and indirect jump instructions, assigning one general purpose register as the stack pointer, say R29. Suppose JAL stores return address in R31:
Calling a procedure Before the JAL instruction to call a procedure, instructions decrement R29 and copy R31 onto the memory stack: call: SUB R29,R29,4 ;Decrement stack pointer ST [R29],R31 ;Return address on stack JAL proc1 ;jump to proc1 and store ;return address in R31
Returning from a procedure Use J [R31] to return and then copy top the memory stack in R31 and increment R29 : JAL proc1 LD R31,[R29] ;restore return address in R31 ADD R29,R29,4 ;Increment stack pointer J[31] End of procedure
3. Passing Arguments (actual parameters) and Returning Results For a procedure which does not call another procedure (leaf procedure) register could be used for passing arguments and returning results. For non-leaf procedures, stack can be used to pass arguments to procedure by placing arguments on stack before call and extracting them off stack from within procedure. Similarly results can be placed on stack prior to returning and extracted off stack afterwards. Need instructions to place values onto stack and instruction to extract values from stack (both, adjusting stack pointer accordingly).
Stack Data Transfer Instructions CISCs (Complex Instruction Set Computers) usually provide a named stack pointer (SP) and special push and pop instructions: PUSH Instruction PUSH R2 ;Copy R2 register onto stack Copies the contents of a location onto the top of the stack, adjusting stack pointer according (decrementing SP by 4 for a 4-byte transfer). POP Instruction POP R2 ;Copy top of stack into R2 register Copies top of the stack into a location, adjusting the stack pointer accordingly (incrementing SP by 4 for a 4-byte transfer).
Passing Parameter thro Stack to Procedure Assume a procedure with one int parameter, x, i.e. proc1(x). xheld in R1: . . . PUSH R1 CALL proc1 POP R1 . . . Procedure proc1 . . ; access stack get R1 . . RET Mechanics of getting parameter from stack a little complicated as it requires a study of contents of the stack to find where R1 is on stack. An addition pointer called frame pointer used.
4. Saving registers The stack can be used to save the contents of registers prior to being reused inside the procedure. Afterwards, registers can be restored from the contents of the stack. Saving/restoring registers can be done by called procedure or by calling program - Probably best done inside called procedure.
Saving Registers within Procedure . . . . CALL proc1 POP R1 . . . R1 and R2 used in main program Procedure proc1 PUSH R1 ;save registers to be PUSH R2 ;reused, say R1 and R2 . ;here R1 and R2 reused . . POP R2 ;restore registers POP R1 RET Notice reverse order