Factorial function in Java:
public class Fac { public static int fac(int n) { if (n == 0) return(1); <--- base case else { return( n * fac(n-1) ); <--- recursive case } } static int result, k=4; public static void main( ) { result = fac(k); } } |
You already learned how to code a recursive function !
The main( ) function must pass the parameter k (fac(k)) using the runtime stack:
main: /* ------------------------------------------------- Pass parameter k (using stack) ------------------------------------------------- */ movw r0, #:lower16:k movt r0, #:upper16:k ldr r0, [r0] // r0 = k push {r0} // Pass k using the program stack /* ------------------------------------------------------ call fac(k) ------------------------------------------------------ */ bl fac add sp, sp, #4 // Clean up the parameter k from the stack /* ----------------------------------------------------------------- Assign 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 result |
The fac(int n) function has 1 parameter (n) and no local variables
Therefore, the stack frame structure created (and used by fac( )) is as follows:
Stack frame of the fac( ) method: SP FP -----> +---------------------+ 0 | old Frame Pointer | (4 bytes) +---------------------+ 4 | Return Address | (4 bytes) +---------------------+ 8 | Parameter n | addr(n) = FP + 8 +---------------------+ |
You just pass n-1 as parameter and call the factorial function using bl fac:
fac: /* ========================================================== 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 omit this instruction....) /* =============================================== 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 // Calls: fac( ) with parameter = (n-1) !!! add sp, sp, #4 // Clean up parameter (n-1) from stack //// ** Right here and now: r0 = fac(n-1) !!! //// Compute n*fac(n-1) next ldr r1, [fp, #8] // r0 = n mul r0, r1, r0 // r0 = n*fac(n-1) // NOTE: r0 has the correct return value !!! // return - with n*fac(n-1) inside 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 |