// // Factorial (recursive) function // /* -------------------------------------------------- Define required labels for EGTAPI -------------------------------------------------- */ .global main, Stop, CodeEnd, DataStart, DataEnd .global fac, k, result /* -------------------------------------------------- Begin of the program instructions -------------------------------------------------- */ .text main: // result = fac(k) /* ------------------------------------------------- Pass parameter k (using stack) ------------------------------------------------- */ movw r0, #:lower16:k movt r0, #:upper16:k ldr r0, [r0] push {r0} /* ---------------------------------------------------------------- call result = fac(k) ---------------------------------------------------------------- */ bl fac 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 fac(int n) Stack frame structure: old FP <--------------------------------- FP old LR (ret addr) n +8 Body of fac(n) if ( n == 0 ) return 1; else return n*fac(n-1); ---------------------------------------------------------------- */ fac: // When fac 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 // (I could delete this instruction....) /* =============================================== 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 else // n != 0 --> Goto "else" 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 else: // Compute: n*fac(n-1) //// Compute fac(n-1) first ldr r0, [fp, #8] // r0 = n sub r0, r0, #1 // r0 = n-1 push {r0} // pass (n-1) to fac on stack bl fac add sp, sp, #4 // Clean up parameter (n-1) from stack //// ** Right now, r0 = fac(n-1) !!! ldr r1, [fp, #8] // r0 = n mul r0, r1, r0 // r0 = n*fac(n-1) // NOTE: r0 has the correct return value !!! // return n*fac(n-1) 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