First Recursive Function: Factorial

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 !

Coding the main( ) 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 structure of the stack frame of the fac( ) function
 

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 
              +---------------------+
   

Coding the fac( ) (recursive) function

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