/* * COSC 065 - Hardware Systems * Fall 2005 * D.W. Brylow * Lecture 19 deomonstration * A recursive Fibonacci function with activation record. */ #include .rodata FMT: .string "fibonacci(%d) = %d\n" .text .globl main #define X r15 main: /* Function prolog. */ /* Sets up environment for user program to execute. */ stwu r1,-32(r1) /* Make room on Stack for O/S values. */ mflr r0 /* Store O/S return address on Stack. */ stw r0,36(r1) stw r31,28(r1) /* Store O/S frame pointer on Stack. */ mr r31,r1 /* new stack top is now frame pointer. */ /* Start of your program. */ loopmain: bl getInt mr X, r3 cmpwi r3, -1 beq done bl fib mr r5, r3 print: lis r3, FMT@ha addi r3, r3, FMT@l mr r4, X bl printf b loopmain /* End of your program. */ done: /* Function epilogue. */ /* Restores the environment from the O/S. */ mr r1, r31 /* Discard stack below frame pointer. */ lwz r31,28(r1) /* Restore O/S frame pointer. */ lwz r0, 36(r1) mtlr r0 /* Restore O/S return address. */ lwz r1, 0(r1) /* Restore O/S Stack pointer. */ li r3, 0 /* Return value of 0 (normal exit). */ blr /* Return to Operating System. */ /********************** * Fibonacci Function * **********************/ /* Need room for: * parent LR 36(FP) * parent FP 28(FP) * parent SP 0(FP) * temp1 8(FP) * temp2 12(FP) * param 'x' 16(FP) * 6 words * 4 bytes = 24 bytes. Round up to 32 (multiple of 16) * Frame Size (size of Activation Record) = 32 * * ACTIVATION RECORD LAYOUT * * +---------+ * 36 |LR_parent| * +---------+ ^ * 32 |SP_old | | parent's stack frame * +---------+ -------+ * 28 |FP_parent| * +---------+ * 24 | ? | * +---------+ * 20 | ? | * +---------+ * 16 | x | * +---------+ * 12 | temp2 | * +---------+ * 8 | temp1 | * +---------+ * 4 |LR_child | * +---------+ ^ * 0 |SP_parent| | fib's stack frame * +---------+ -------+ <--- FP_fib */ fib: /* PROLOG: Build stack frame. */ stwu r1, -32(r1) /* Allocate stack frame. */ mflr r0 /* Save link register */ stw r0, 36(r1) /* in parent's stack frame. */ stw r31, 28(r1) /* Save frame pointer. */ mr r31, r1 /* Set new frame pointer. */ /* PROLOG END */ cmpwi r3, 1 /* Recursive base case. */ ble fibdone /* If (x == 1) return x. */ stw r3, 16(r31) /* Preserve x in stack frame. */ subi r3, r3, 1 /* Calculate (x - 1) */ bl fib /* Recursive fib(x - 1) */ stw r3, 8(r31) /* temp1 = fib(x - 1) */ lwz r3, 16(r31) /* Get pristine x from frame. */ subi r3, r3, 2 /* Calculate (x - 2). */ bl fib /* Recursive fib(x - 2). */ stw r3, 12(r31) /* temp2 = fib(x - 2). */ lwz r3, 12(r31) /* Add together temp1 and temp2 */ lwz r4, 8(r31) add r3, r3, r4 fibdone: /* EPILOGUE: Tear down frame. */ mr r1, r31 /* Reset SP to equal FP. */ lwz r31, 28(r1) /* Restore parent FP. */ lwz r0, 36(r1) /* Restore parent LR. */ mtlr r0 lwz r1, 0(r1) /* Restore parent stack. */ blr /* Return to parent function. */ /* EPILOGUE END */ /******************* * getInt Function * *******************/ #define ACCUM r13 #define OLDLR r14 getInt: mflr OLDLR li ACCUM, 0 loopInt: bl getchar cmpwi r3, 0x0A beq doneInt cmpwi r3, -1 bne loop2int li ACCUM, -1 b doneInt loop2int: cmpwi r3, 0x30 blt loopInt cmpwi r3, 0x39 bgt loopInt subi r3, r3, 0x30 mulli ACCUM, ACCUM, 10 add ACCUM, ACCUM, r3 b loopInt doneInt: mr r3, ACCUM mtlr OLDLR blr