180 likes | 350 Views
ELEC 5200-001/6200-001 Computer Architecture and Design Spring 2008 Executing a Recursive Procedure (Chapter 2). Vishwani D. Agrawal James J. Danaher Professor Department of Electrical and Computer Engineering Auburn University, Auburn, AL 36849 http://www.eng.auburn.edu/~vagrawal
E N D
ELEC 5200-001/6200-001Computer Architecture and DesignSpring 2008Executing a Recursive Procedure(Chapter 2) Vishwani D. Agrawal James J. Danaher Professor Department of Electrical and Computer Engineering Auburn University, Auburn, AL 36849 http://www.eng.auburn.edu/~vagrawal vagrawal@eng.auburn.edu ELEC 5200-001/6200-001 Lecture 6
Memory and Registers Memory 0 4 8 12 . 4n . . . . . byte addr. Word 0 zero Register 0 Word 1 Register 1 Word 2 Register 2 Register 3 Word n Register 4 Word n+1 Register 5 . . . Register 31 jump addr. ELEC 5200-001/6200-001 Lecture 6
Data Placement in Memory $s0-$s7 saved in Stack during procedure $sp Stack Dynamic data $gp Static data Machine code (text) pc Reserved 0 ELEC 5200-001/6200-001 Lecture 6
Register Convention The following convention is understood and used by all calling (caller) and called (callee) programs. Preserved Not preserved Saved reg. $s0 - $s7 Temp. reg. $t0 - $t9 Stack pointer reg. $sp Argument reg. $a0 - $a3 Return addr. Reg. $ra Return value reg. $v0 - $v1 Stack above the stack pointer Stack below the stack pointer ELEC 5200-001/6200-001 Lecture 6
Caller Actions • Put parameter values in argument registers, $a0 - $a3 • Save registers in memory • Jump and link to calee: jal “calee’s address” • Put return address (PC+4) in $ra • Jump to “calee’s address” • On return, restore saved registers from memory • Find returned parameters in value registers, $v0 - $v3 ELEC 5200-001/6200-001 Lecture 6
Caller Saving and Restoring • Before the call • Push the stack pointer • Save those temporary registers in the memory, whose contents will be required later; calee may change these. • After the call (on return) • Restore temporary registers that were saved • Pop the stack pointer ELEC 5200-001/6200-001 Lecture 6
Calee Actions • Save in memory any registers among $s0 - $s7 that might be changed; caller expects them to be unchanged. • Use arguments in registers $a0 – $a3. • Place results in value registers $v0 – $v3. • Restore saved registers from memory. • Leave stack pointer in the same state as when the call was initiated. • Jump to address in register $ra ( jr $ra ) ELEC 5200-001/6200-001 Lecture 6
Calee Example • Procedure proc uses register $s0 • Assembly code: proc: addi $sp, $sp, -4 # push stack down sw $s0, 0($sp) # save $s0 . Assembly code of proc . lw $s0, 0($sp) # restore $s0 addi $sp, $sp, 4 # pop 1 word off stack jr $ra # return ELEC 5200-001/6200-001 Lecture 6
When Calee becomes a Caller • Saving and restoring of saved and temporary registers is done same as described before. • May reuse argument registers ($a0 - $a3); they are saved and restored as necessary. • Must reuse $ra; its content is saved in memory and restored on return. ELEC 5200-001/6200-001 Lecture 6
Example: Program→Callee A→Calee B Main program Procedure A(arg1) Procedure B(arg1) . . addi $sp, $sp, -8 sw $ra, 4($sp) sw $a0, 0($sp) addi $a0, $zero, 7 jal B lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 . . jr $ra . . addi $a0, $zero, 3 jal A . . . . . jr $ra ELEC 5200-001/6200-001 Lecture 6
Example: A Recursive Procedure Int fact (n) { if (n < 1) return (1); else return (n * fact (n-1)); } This procedure returns factorial of integer n, i.e., n! = n × (n-1) × (n-2) × . . . × 2 × 1 = n × (n-1)! Boundary case, 0! = 1 ELEC 5200-001/6200-001 Lecture 6
Flowchart of fact positive integer n n < 1 Yes v(n) = 1 No v(n) = n * v(n-1) Return v(n) ELEC 5200-001/6200-001 Lecture 6
Example: Compute 4! n = 4 Main program calls fact, $a0 = 4 fact calls fact, $a0 = 3 fact calls fact, $a0 = 2 fact calls fact, $a0 = 1 fact calls fact, $a0 = 0 Returns $v0 = $v0 * $a0 = 24 Returns $v0 = $v0 * $a0 = 6 Returns $v0 = $v0 * $a0 = 2 Returns $v0 = $v0 * $a0 = 1 Returns $v0 = 1 v(4) = 4 * v(3) v(3) = 3 * v(2) v(2) = 2 * v(1) v(1) = 1 * v(0) v(0) = 1 ELEC 5200-001/6200-001 Lecture 6
What to Save? • Recursive procedure will call itself. So, • will reuse return address register $ra • will change argument register $a0 • These two registers must be saved. ELEC 5200-001/6200-001 Lecture 6
Saved Registers for 4! Example Initial $sp Return address within main program Argument register, $a0 = 4 Return address within fact Argument register, $a0 = 3 Return address within fact Argument register, $a0 = 2 Return address within fact Argument register, $a0 = 1 } fact calls fact, $a0 = 3 fact calls fact, $a0 = 2 fact calls fact, $a0 = 1 fact calls fact, $a0 = 0 } } } $sp ELEC 5200-001/6200-001 Lecture 6
Assembly Code for fact fact: addi $sp, $sp, -8 # adjust stack for two items sw $ra, 4($sp) # save return address of caller sw $a0, 0($sp) # save caller supplied argument n slti $t0, $a0, 1 # $t0 = 1, if n ≤ 1, i.e., n = 0 beq $t0, $zero, L1 # go to L1, if n ≥ 1 addi $v0, $zero, 1 # return $v0 = 1 to caller addi $sp, $sp, 8 # no need to restore registers, since none was changed, but must restore stack pointer jr $ra # return to caller instruction after jal ELEC 5200-001/6200-001 Lecture 6
Assembly Code Continued L1: addi $a0, $a0, -1 # set $a0 to n-1 jal fact # call fact with argument n-1 lw $a0, 0($sp) # on return from fact, restore n lw $ra, 4($sp) # restore return address addi $sp, $sp, 8 # adjust stack pointer mul $v0, $a0, $v0 # n! = n × (n-1)! jr $ra # return to caller ELEC 5200-001/6200-001 Lecture 6
Execution of fact for n ≥ 1 Call Caller #a0 $ra Returned $v0 Sequence 1 Main Program n PC+4 n×(n-1)! 2 fact n-1 L1+8 (n-1)×(n-2)! 3 fact n-2 L1+8 (n-2)×(n-3)! fact . fact . fact . n-2 fact 3 L1+8 3×2 = 6 n-1 fact 2 L1+8 2×1 = 2 n fact 1 L1+8 1×1 = 1 n+1 fact 0 L1+8 1 ELEC 5200-001/6200-001 Lecture 6