ARM GAS  fac.s 			page 1


   1              	//
   2              	//  Factorial (recursive) function
   3              	//
   4              	
   5              	/* --------------------------------------------------
   6              	   Define required labels for EGTAPI
   7              	   -------------------------------------------------- */
   8              	        .global main, Stop, CodeEnd, DataStart, DataEnd
   9              		.global fac, k, result
  10              	
  11              	/* --------------------------------------------------
  12              	   Begin of the program instructions
  13              	   -------------------------------------------------- */
  14              		.text
  15              	main:
  16              	
  17              		//  result = fac(k)
  18              	
  19              	        /* -------------------------------------------------
  20              		   Pass parameter k (using stack)
  21              	           ------------------------------------------------- */
  22 0000 000000E3 		movw	r0, #:lower16:k
  23 0004 000040E3 		movt	r0, #:upper16:k
  24 0008 000090E5 		ldr	r0, [r0]
  25 000c 04002DE5 		push	{r0}
  26              	
  27              		/* ----------------------------------------------------------------
  28              		   call result = fac(k)
  29              		   ---------------------------------------------------------------- */
  30 0010 FEFFFFEB 		bl	fac
  31 0014 04D08DE2 		add	sp, sp, #4	// Clean up the parameter k
  32              	
  33              	        /* -----------------------------------------------------------------
  34              		   Save return value (in r0) to variable result 
  35              	           ----------------------------------------------------------------- */
  36 0018 001000E3 		movw	r1, #:lower16:result  // Do NOT use r0 !!!
  37 001c 001040E3 		movt	r1, #:upper16:result  // (Because r0 contains the return value)
  38              	
  39 0020 000081E5 		str	r0, [r1]	     // This will store return value in sum
  40              	
  41              	Stop:
  42 0024 0000A0E1 		nop			   // Stop point of main( )
  43              	
  44              	
  45              	
  46              	
  47              	
  48              	/* ----------------------------------------------------------------
  49              	   Function int fac(int n)
  50              	
  51              	        Stack frame structure:
  52              	
  53              			old FP   <--------------------------------- FP
  54              			old LR (ret addr)
  55              			  n			+8
  56              	
  57              	   Body of fac(n)
ARM GAS  fac.s 			page 2


  58              	
  59              		if ( n == 0 )
  60              		   return 1;
  61              		else
  62              		   return n*fac(n-1);
  63              	   ---------------------------------------------------------------- */
  64              	
  65              	fac:
  66              	
  67              		// When  fac  begins, we will have: n  on the stack
  68              	
  69              	
  70              		/* ==========================================================
  71              		   Function Prelude: complete the stack frame structure
  72              		   ========================================================== */
  73 0028 04E02DE5 		push	{lr} 		// Save LR (return address)
  74 002c 04B02DE5 		push	{fp} 		// Save FP (used by caller)
  75 0030 0DB0A0E1 		mov	fp, sp 		// Mark the stack top location before
  76              					// allocating any local variables
  77 0034 00D04DE2 		sub	sp, sp, #0	// Allocate 0 int variables on the stack
  78              					// (I could delete this instruction....)
  79              	
  80              	
  81              	
  82              		/* ===============================================
  83              		   We completed the stack frame
  84              		   Now we can write the function body
  85              		   =============================================== */
  86              	        // if ( n == 0 )
  87 0038 08009BE5 		ldr	r0, [fp, #8]	// r0 = n
  88              	
  89 003c 000050E3 		cmp	r0, #0		// Check n == 0
  90 0040 0300001A 		bne	else		// n != 0 --> Goto "else" part
  91              	
  92              		// return 1
  93              	
  94              		///// put return value 1 in return location r0
  95 0044 0100A0E3 		mov	r0, #1
  96              	
  97              		/* =============================================================
  98              		   Function Postlude: de-allocate local variable and restore FP
  99              		   ============================================================= */
 100 0048 0BD0A0E1 		mov	sp, fp		// De-allocate local variables
 101 004c 04B09DE4 		pop	{fp}		// Restore fp
 102 0050 04F09DE4 		pop	{pc} 		// Return to the caller
 103              	
 104              	else:
 105              		// Compute: n*fac(n-1)
 106              	
 107              		//// Compute fac(n-1) first
 108 0054 08009BE5 		ldr	r0, [fp, #8]	// r0 = n
 109 0058 010040E2 		sub	r0, r0, #1	// r0 = n-1
 110              	
 111 005c 04002DE5 		push	{r0}		// pass (n-1) to fac on stack
 112 0060 FEFFFFEB 		bl	fac
 113 0064 04D08DE2 		add 	sp, sp, #4	// Clean up parameter (n-1) from stack
 114              	
ARM GAS  fac.s 			page 3


 115              		//// ** Right now, r0 = fac(n-1) !!!
 116              	
 117 0068 08109BE5 		ldr     r1, [fp, #8]    // r0 = n
 118 006c 910000E0 		mul	r0, r1, r0	// r0 = n*fac(n-1) 
 119              					// NOTE: r0 has the correct return value !!!
 120              	
 121              		// return   n*fac(n-1)  in r0
 122              		/* =============================================================
 123              		   Function Postlude: de-allocate local variable and restore FP
 124              		   ============================================================= */
 125 0070 0BD0A0E1 		mov	sp, fp		// De-allocate local variables
 126 0074 04B09DE4 		pop	{fp}		// Restore fp
 127 0078 04F09DE4 		pop	{pc} 		// Return to the caller
 128              	
 129              	
 130              	
 131              	
 132              	CodeEnd:
 133 007c 0000A0E1 	    	nop
 134              	
 135              	/* --------------------------------------------------
 136              	   Begin of the permanent program variables
 137              	   -------------------------------------------------- */
 138              		.data
 139              	DataStart:
 140              	
 141 0000 03000000 	k:	.4byte	3
 142 0004 00000000 	result: .skip   4
 143              	
 144              	DataEnd:
 145              	
 146              		.end
ARM GAS  fac.s 			page 4


DEFINED SYMBOLS
               fac.s:15     .text:0000000000000000 main
               fac.s:41     .text:0000000000000024 Stop
               fac.s:132    .text:000000000000007c CodeEnd
               fac.s:139    .data:0000000000000000 DataStart
               fac.s:144    .data:0000000000000008 DataEnd
               fac.s:65     .text:0000000000000028 fac
               fac.s:141    .data:0000000000000000 k
               fac.s:142    .data:0000000000000004 result
               fac.s:22     .text:0000000000000000 $a
               fac.s:104    .text:0000000000000054 else
               fac.s:142    .data:0000000000000004 $d

NO UNDEFINED SYMBOLS
