// // Fibonnaci(recursive) function // /* -------------------------------------------------- Define required labels for EGTAPI -------------------------------------------------- */ .global main, Stop, CodeEnd, DataStart, DataEnd .global fib, k, result /* -------------------------------------------------- Begin of the program instructions -------------------------------------------------- */ .text main: // result = fib(k) /* ------------------------------------------------- Pass parameter k (using stack) ------------------------------------------------- */ movw r0, #:lower16:k movt r0, #:upper16:k ldr r0, [r0] push {r0} /* ---------------------------------------------------------------- call result = fib(k) ---------------------------------------------------------------- */ bl fib add sp, sp, #4 // Clean up the parameter k /* ----------------------------------------------------------------- Save return value (in r0) to variable result ----------------------------------------------------------------- */ movw r1, #:lower16:result // Do NOT use r0 !!! movt r1, #:upper16:result // (Because r0 contains the return value) str r0, [r1] // This will store return value in sum Stop: nop // Stop point of main( ) /* ---------------------------------------------------------------- Function int fib(int n) Stack frame structure: old FP <--------------------------------- FP old LR (ret addr) n +8 Body of fib(n) if ( n == 0 ) return 1; if ( n == 1 ) return 1; else return fib(n-1) + fib(n-2); ---------------------------------------------------------------- */ fib: // When fib begins, we will have: n on the stack /* ========================================================== Function Prelude: complete the stack frame structure ========================================================== */ push {lr} // Save LR (return address) push {fp} // Save FP (used by caller) mov fp, sp // Mark the stack top location before // allocating any local variables sub sp, sp, #0 // Allocate 0 int variables on the stack /* =============================================== We completed the stack frame Now we can write the function body =============================================== */ // if ( n == 0 ) ldr r0, [fp, #8] // r0 = n cmp r0, #0 // Check n == 0 bne else1 // n != 0 --> Goto "else1" part // return 1 ///// put return value 1 in return location r0 mov r0, #1 /* ============================================================= Function Postlude: de-allocate local variable and restore FP ============================================================= */ mov sp, fp // De-allocate local variables pop {fp} // Restore fp pop {pc} // Return to the caller else1: // if ( n == 1 ) ldr r0, [fp, #8] // r0 = n cmp r0, #1 // Check n == 1 bne else2 // n != 1 --> Goto "else2" part // return 1 ///// put return value 1 in return location r0 mov r0, #1 /* ============================================================= Function Postlude: de-allocate local variable and restore FP ============================================================= */ mov sp, fp // De-allocate local variables pop {fp} // Restore fp pop {pc} // Return to the caller else2: // Compute: fib(n-1) + fib(n-2) //// Compute fib(n-1) first ldr r0, [fp, #8] // r0 = n sub r0, r0, #1 // r0 = n-1 push {r0} // pass (n-1) to fib on stack bl fib add sp, sp, #4 // Clean up parameter (n-1) from stack //// ** Right now, r0 = fib(n-1) --- we can't lose this value !!! //// ** But we can't compute fib(n-1) + fib(n-2) without fib(n-2) //// ** We will call fib to compute fib(n-2) //// ** We MUST save r0 on the STACK !!! push {r0} // Save fib(n-1) on the stack //// Compute fib(n-2) ldr r0, [fp, #8] // r0 = n sub r0, r0, #2 // r0 = n-2 push {r0} // pass (n-2) to fib on stack bl fib add sp, sp, #4 // Clean up parameter (n-2) from stack //// ** Right now, r0 = fib(n-2) - we can now compute fib(n-1)+fib(n-2) pop {r1} // Retrieve fib(n-1) from the stack add r0, r1, r0 // r0 = fib(n-1) + fib(n-2) // NOTE: r0 has the correct return value !!! // return fib(n-1)+fib(n-2) in r0 /* ============================================================= Function Postlude: de-allocate local variable and restore FP ============================================================= */ mov sp, fp // De-allocate local variables pop {fp} // Restore fp pop {pc} // Return to the caller CodeEnd: nop /* -------------------------------------------------- Begin of the permanent program variables -------------------------------------------------- */ .data DataStart: k: .4byte 3 result: .skip 4 DataEnd: .end