Chapter9 - Chapter 9: Procedures EEC 70 Fall 2010 Professor...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: Chapter 9: Procedures EEC 70 Fall 2010 Professor Wilken 1 Why Have Procedures? Software engineering perspective: Software • Provides program modularity Simplifies program design, modification, debugging Simplifies Allows different programmers to write different parts of the same Allows program program Architecture/Compiler perspective: Architecture/Compiler • Allows reduction in program size in exchange for Allows somewhat reduced performance (overhead of Call, Call Return, and certain other overhead) Return main main A Call A Call A add xor return vs: add xor add xor 2 Compilers and Procedures Just because you use a procedure (e.g., for software engineering purposes) does not mean the compiler will produce a procedure the • Compiler can optimize size vs. speed for you You write: The compiler produces: main A main Call A add xor return add xor Call B B mult sub return mult sub Code is smaller and faster! 3 Compilers and Procedures Using procedures, the programmer tells the compiler where there are common segements of segements of code main A Call A The compiler may inline inline one or more of the one procedures calls to increase peformance peformance 109 add xor return mult sub Or leave some or all procedure calls to save space 4 Compilers and Procedures A good compiler can also automatically identify equivalent code segments that were not indicated by the programmer(s) programmer(s May then outline (create) procedures to outline (create) save space save You write: main The compiler produces: main add B,C,D xor E,F,G A Call A add B,C,D xor E,F,G Call A xor E,F,G add B,C,D 5 Procedure Execution Steps 1. Save parameters. Where? • In registers (fast) or in memory (slow) 2. Save return address. Where? • In register (fast) or in memory (slow) 3. Call procedure. How? • new jump instruction 4. Allocate memory space to store procedure’s variables (local variables). Why? variables • Variables are used only temporarily, space can be Variables reclaimed upon return reclaimed • For recursive procedure call, must have multiple For copies of local variables, one for each recursion copies How? • Using a special stack data structure, the system stack Using system 6 Procedure Execution Steps (cont.) 5. Execute the procedure 6. Deallocate local variables. How? Pop them off the system stack Pop 7. Save return values, if any. Where? In registers (fast) or in memory (slow) In 8. Get return address 9. Return. How? New jump instruction New 7 Procedure Call MAL has a special jump instruction for procedure calls, Jump and Link (jal) procedure Instruction’s assembly format: Instruction jal proc_label Instruction’s action: Instruction • Program unconditionally jumps to the address Program represented by proc_label proc_label • Return address (address of instruction after Return jal) is saved in $31, called the link register jal is link because is links the procedure back to the because return location. return 8 Procedure Return A new instruction Jump Register (jr) is used for new is returning from a procedure returning Instruction’s assembly format: Instruction jr $x Instruction’s action: Instruction • Program unconditionally jumps to the address Program contained in register x. contained Together jal and jr allow for simple and fast jal and jr allow subroutine calls/returns: subroutine jal proc1 proc1: jr $31 9 Other Uses for jr Other jr 26 Jump instruction (j) can “only” access 2 Jump can locations (large, but not strictly all locations). jr can access all locations: jr la $18, target jr $18 jr is also used in implement case (switch) jr is statements: statements: la $18, branch_table add $20, $18, $19 branch_table: # $19 contains # case number x4 jr $20 b case_0 b case_1 b case_2 ... 10 Nested Procedure Calls We have a problem: when a procedure A calls another procedure B (a nested procedure call) nested the contents of $31 are overwritten and the return address for A is lost: main sub. A jal A jal B sub. B jr $31 jr $31 Solution 1: transfer the return address to another register another • In A, before call to B: • move $16,$31 # save return address in reg 16 To return from A: jr $16 # return address is in reg 16, go for it 11 Recursive Procedure Calls It is possible for a procedure to conditionally call itself, a recursive procedure call recursive • (e.g., see Problem 9.8) The number or recursive calls can be indefinite ⇒ cannot save return address in registers cannot Solution 2: save return addresses on the system stack stack • want a stack, because addresses are needed in the want reverse order they are produced. reverse By convention, register $29 is designated as the system stack pointer $sp $sp 12 Stacking the Return Address The MIPS system stack grows from highThe numbered memory toward low-numbered numbered memory memory • $29 $29 points to empty location above the stack Proc1: sw Proc1: addi ... $31, 0($29) $29, $29, -4 $29, # store return address to the stack # expand stack size by one integer beq jal ... $8, $9, exit Proc1 # test some condition # recursive call lw addi jr jr $10, 4($29) $29, $29, 4 $10 # load return address from the stack # contract stack size by one integer contract # return to the calling routine exit: 13 Passing Parameters A fast way to pass parameters to a procedure is using registers registers • MIPS uses the software convention that the first 4 MIPS parameters are passed in registers $4-$7 parameters • Handles most procedure calls, because usually few Handles parameters are passed parameters • Additional parameters passed on the system stack move move move move addi addi sw sw sw jal ... $4, param1 $5, param2 $6, param3 $7, param4 $7, $29, $29, -12 $29, $31, 4($29) $14, 8($29) $15, 12($29) Proc1 # make room on stack for two params # store return address at top of stack # store 6th param in next stack location # store 5th param in next stack location # call procedure 14 Passing Parameters Proc1: lw lw lw ... jr $31 $8, 8($29) $9, 4($29) # params 1-4 are in registers $4-$7, # can use them directly from those regs. # put 5th parameter in a register put # put 6th parameter in a register # return to caller return 15 Return Values Procedure return values are handled similarly: similarly: • first 2 return values are returned in registers, $2 first and $3 and • additional return values are passed back on the additional stack stack 16 Saving and Restoring Registers For procedure A calling procedure B, the writer of A must be concerned that procedure B might destroy the registers A is using destroy To be safe, A could save all its active registers to the stack, restore them after B returns to addi sw sw sw sw jal lw lw lw lw $29, $29, -16 $29, $31, 4($29) $10, 8($29) $11, 12($29) $12, 16($29) ProcB $31, 4($29) $10, 8($29) $11, 12($29) $12, 16($29) # make room on stack for saving registers # save return address # save reg. 10 # save reg. 11 # save reg. 12 # call procedure # load return address # restore reg. 10 # restore reg. 11 # restore reg. 12 This is slow. May be unnecessary: what if B doesn’t use these registers? doesn 17 Saving and Restoring Registers (cont.) Instead, B could save on the stack the values in all registers B is going to use, restore the values prior to return prior addi sw sw sw $29, $29, -12 $29, $16, 4($29) $17, 8($29) $18, 12($29) # make room on stack for saving registers # save reg. 16 # save reg. 17 # save reg. 18 <procedure body> lw lw lw addi jr $16, 4($29) $17, 8($29) $18, 12($29) $29, $29, 12 $31 # restore reg. 16 # restore reg. 17 # restore reg. 18 # deallocate stack space This is slow. May be unnecessary: what if A doesn’t use these registers? doesn 18 Caller-Saved/Callee-Saved Registers To avoid unnecessary register saves/restores, software convention divides the registers into two sets: two • callee saved registers (also called saved registers): (also saved ): these registers are preserved across a call, the caller does not have to worry about saving them. The callee must save them if it wants to use them. The 8 callee saved registers are $16-$23, $30 ($s0-$s7) callee • caller saved registers (also called temporary (also registers): these registers may be destroyed by the registers): callee without saving them. The caller must save these registers if it was to preserve the values these 19 registers are caller saved: $1-$7, $8-$15 ($t0-$t7), $24-25 19 25 ($t8-$t9),$28, $31 ($t8 19 Dynamic Storage Allocation A procedure’s local variables can be allocated on procedure local the system stack, on procedure entry the • Allows multiple instances of the same variable for Allows recursive calls recursive • Provides proper variable scope for nested calls • Allows easy deallocation For example, you want write a procedure that has two For local index variables. Rather than write: local .data i: j: .word .word You write: .text myproc: addi $29, $29, -8 #allocate space for two local addi #allocate #variables #variables 20 Dynamic Storage Allocation (cont.) The first index variable is access as: lw/sw $7, 4($29) # its location is on the top of the lw/sw stack stack The second index variable is access as: lw/sw $9, 8($29) # its location is second from top its of stack of Local variables are pushed on top of return address and any parameters that were passed on stack: and $sp “i” “j” ret. address param2 param1 ... 21 Dynamic Storage Allocation (cont.) The only local scalar variables allocated scalar variables space on the stack are those that cannot stay in a register their entire life. stay 22 Stack Frame The set of variables on the stack associated with a procedure is called a stack frame. stack Stack frame is allocated at call, deallocate at return. The stack is really a stack of stack frames: The 23 Stack Frame (cont.) Assume prior procedure is called recursively twice: twice: $sp “i” “j” ret. address param2 param1 “i” “j” ret. address param2 param1 ... 24 Stack Frame (cont.) Consider a more interesting example: Consider $sp main () { A();} D Frame A() { B(); } C Frame B() { C(); } C() { D(); } B Frame D() {} A Frame 25 Stack Frames (cont.) Stack frames give variables proper scope: Stack • current procedure can only access variables within current the current stack frame the All frame entries are accessed via lw/sw $y, X($29) lw/sw • the offset X is known by the compiler/assembly the programmer because it has a fixed position within the stack frame. the 26 Local Arrays All local variables not in a register for their entire life All local are allocated to the system stack, even arrays. Popped off at procedure exit. Popped $sp a[ ] “i” “j” ret. address param2 param1 ... 27 Local User Stack Can allocate an unbounded user stack atop the system stack. Push/Pop user stack via addi $sp,$sp,constant $sp my_stack “i” “j” ret. address param2 param1 param1 ... 28 Frame Pointer If $sp is moving during procedure execution (e.g., local user stack) (e.g., • how to access fixed-position elements on the stack position (e.g., return address)? (e.g., • how to completely deallocate the stack? Frame pointer points to bottom of stack frame Frame • Fixed-position elements are accessed relative to $fp: position lw/sw $y, X($fp) lw/sw • stack is deallocated by setting $sp equal to $fp • $fp can be any one of the saved registers MIPS software convention does not designate one MIPS Many compilers will designate their own Many 29 Frame Pointer (cont.) Must save the caller’s $fp onto the stack, and Must $fp restore it prior to exit (like any other saved register). $sp “i” $fp old $fp ret. address param2 param1 param1 “k” old $fp ret. address param1 ... 30 Main () as a Procedure main () is called by the operating system, somewhat like a procedure, except: somewhat • Return address is not saved, so called using Return jump rather than JAL jump rather JAL OS does not necessarily want to execute the next instruction after jump to user code instruction • Return is via a special instruction SYSCALL, Return SYSCALL which jumps to a special return location in the OS. the User is blocked from jumping to other locations in the OS, for security and reliability the SAL done SYSCALL done SYSCALL 31 Global Data Non-local data that can be accessed in all Non local procedures (global data) is kept in a special procedures is region of memory region • Global data space is accessed via global pointer Global ($gp) ($gp) • Created by usual .word, .float, .byte directives code global global data data system stack 32 Heap Dynamically allocated memory (e.g, C: Dynamically C: malloc/new) is allocated from a memory malloc/new) area called the heap heap • Managed by the operating system • Heap grows in opposite direction from the Heap stack stack code global global data data heap stack 33 ...
View Full Document

Ask a homework question - tutors are online