// // A recursive function demo // /* -------------------------------------------------- Define required labels for EGTAPI -------------------------------------------------- */ .global main, Stop, CodeEnd, DataStart, DataEnd .global f, result /* -------------------------------------------------- Begin of the program instructions -------------------------------------------------- */ .text main: // result = f(2,4) /* ------------------------------------------------- Pass parameters (using stack) ------------------------------------------------- */ mov r0, #4 push {r0} // Pass param 2 (=4) mov r0, #2 push {r0} // Pass param 1 (=2) /* ---------------------------------------------------------------- call result = f(2,4) ---------------------------------------------------------------- */ bl f add sp, sp, #8 // Clean up the parameters /* ----------------------------------------------------------------- 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 f(int a, int b) Stack frame structure: i -8 s -4 old FP <--------------------------------- FP old LR (ret addr) a +8 b +12 Body of f(a,b) s = 0; for (i = a; i < b; i++) s = s + f(a+1, b-1) + 1; return s; ---------------------------------------------------------------- */ 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 CodeEnd: nop /* -------------------------------------------------- Begin of the permanent program variables -------------------------------------------------- */ .data DataStart: result: .skip 4 DataEnd: .end