Second Recursive Function

Consider the following recursive function with local variables:

 public class Recurse
 {
   public static int f(int a, int b) 
   {
      int i, s;

      s = 0;
      for (i = a; i < b; i++)
      {
         s = s + f(a+1, b-1) + 1;
      }
      return s;
   }

   public static void main( ) 
   {
      int result = f(2, 5);
   }
} 

DEMO:   /home/cs255001/demo/asm/8-sub/recurse.s

Coding the main( ) function

The main( ) function must pass the parameters (f(2,5)) using the runtime stack:

main:
   /* -------------------------------------------------
      Pass parameters (using stack)
      ------------------------------------------------- */
   mov     r0, #5
   push    {r0}   // Pass 5 (param 2) using the program stack
   mov     r0, #2
   push    {r0}   // Pass 2 (param 1) using the program stack

   /* ------------------------------------------------------
      call f(2,5)
      ------------------------------------------------------ */
   bl      f

   add     sp, sp, #8  // Clean up the parameters 2,5 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 f( ) function
 

The f(int a, int b) function has 2 parameter (a, b) and 2 local variables (i, s)

Therefore, the stack frame structure created (and used by f( )) is as follows:

 Stack frame of the f( ) method:

    SP -----> +---------------------+
          -8  |  Local var i        |  addr(i) = FP - 8 
              +---------------------+
          -4  |  Local var s        |  addr(s) = FP - 4 
    FP -----> +---------------------+                  
           0  |  old Frame Pointer  | (4 bytes)
              +---------------------+
           4  |  Return Address     | (4 bytes)
              +---------------------+
           8  |  Parameter a        |  addr(a) = FP + 8 
              +---------------------+
          12  |  Parameter b        |  addr(b) = FP + 12 
              +---------------------+
   

Coding the f( ) (recursive) function

f:

        // When  f begins, we will have: a,b  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, #8      // Allocate 2 int variables on the stack

        /* ===============================================
           We completed the stack frame
           Now we can write the function body
           =============================================== */
        // s = 0
        mov     r0, #0
        str     r0, [fp, #-4]   // assign 0 to s

        // i = a
        ldr     r0, [fp, #8]    // r0 = a
        str     r0, [fp, #-8]   // assign to i

while:
        // while ( i < b )
        ldr     r0, [fp, #-8]   // r0 = i
        ldr     r1, [fp, #12]   // r1 = b

        cmp     r0, r1          // i ? b
        bge     whileEnd        // Exit for loop

        // We CANNOT compute s + f(a+1, b-1) + 1 without the
        // value (= a number) for: f(a+1, b-1)

        // Compute f(a+1, b-1) first !
        ldr     r0, [fp, #12]   // r0 = b
        sub     r0, r0, #1      // r0 = b-1
        push    {r0}            // pass param2 (b-1)

        ldr     r0, [fp, #8]    // r0 = a
        add     r0, r0, #1      // r0 = a+1
        push    {r0}            // pass param1 (a+1) to f on stack

        bl      f
        add     sp, sp, #8      // Clean up parameter (n-1) from stack

        // We can now compute s + f(a+1, b-1) + 1

        ldr     r1, [fp, #-4]   // r1 = s
        add     r0, r0, r1      // r0 = s + f(a+1, b-1)
        add     r0, r0, #1      // r0 = s + f(a+1, b-1) + 1

        str     r0, [fp, #-4]   // Assign s + f(a+1, b-1) + 1  to s

        // i++
        ldr     r0, [fp, #-8]   // r0 = i
        add     r0, r0, #1      // r0 = i + 1
        str     r0, [fp, #-8]   // Assign i+1  to i

        b       while

whileEnd:
        // return   s  in r0
        ldr     r0, [fp, #-4]   // r0 = s

        /* =============================================================
           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
   

DEMO:   /home/cs255001/demo/asm/8-sub/recurse.s