112 lines
		
	
	
		
			No EOL
		
	
	
		
			4.3 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
		
			No EOL
		
	
	
		
			4.3 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
	AREA RESET, DATA, READONLY
 | 
						|
	EXPORT __Vectors
 | 
						|
__Vectors
 | 
						|
	DCD 0x10001000
 | 
						|
	DCD Reset_Handler
 | 
						|
	ALIGN
 | 
						|
	
 | 
						|
	AREA MYCODE, CODE, READONLY
 | 
						|
	ENTRY
 | 
						|
	EXPORT Reset_Handler
 | 
						|
 | 
						|
; ========================================================================================
 | 
						|
; FACTORIAL.asm - Recursive Factorial Calculation
 | 
						|
; ========================================================================================
 | 
						|
; This program demonstrates recursive factorial computation using ARM assembly.
 | 
						|
; The factorial of a number n (n!) is the product of all positive integers less
 | 
						|
; than or equal to n. This implementation uses the call stack to handle recursion.
 | 
						|
 | 
						|
; ========================================================================================
 | 
						|
; Reset_Handler - Main program execution
 | 
						|
; ========================================================================================
 | 
						|
; Algorithm Overview:
 | 
						|
; 1. Load the input number (5) into R1
 | 
						|
; 2. Call the recursive factorial function (fact)
 | 
						|
; 3. Store the result from R0 to memory location 0x10001000
 | 
						|
; 4. Enter infinite loop for program termination
 | 
						|
 | 
						|
Reset_Handler
 | 
						|
	; Step 1: Load input parameter and call factorial function
 | 
						|
	; Load the number for which to calculate factorial (n = 5)
 | 
						|
	LDR R1, =5                        ; R1 = 5 (input parameter for factorial)
 | 
						|
 | 
						|
	; Call the recursive factorial function
 | 
						|
	; BL (Branch with Link) saves return address in LR and jumps to fact
 | 
						|
	BL fact                           ; Call factorial function, result returned in R0
 | 
						|
 | 
						|
	; Step 2: Store the result
 | 
						|
	; Load destination address into R12
 | 
						|
	LDR R12, =0x10001000              ; R12 = 0x10001000 (result storage address)
 | 
						|
 | 
						|
	; Store the factorial result (in R0) to memory
 | 
						|
	STR R0, [R12]                     ; Store factorial result to [R12]
 | 
						|
 | 
						|
	; Step 3: Program termination
 | 
						|
STOP
 | 
						|
	B STOP                            ; Branch to STOP label (infinite loop)
 | 
						|
 | 
						|
; ========================================================================================
 | 
						|
; fact - Recursive Factorial Function
 | 
						|
; ========================================================================================
 | 
						|
; Recursive algorithm for calculating n!
 | 
						|
; Base case: if n <= 1, return 1
 | 
						|
; Recursive case: return n * factorial(n-1)
 | 
						|
; Parameters: R1 = n (input)
 | 
						|
; Returns: R0 = n! (result)
 | 
						|
; Uses: R2 (temporary register for stack operations)
 | 
						|
 | 
						|
fact
 | 
						|
	; Step 1: Check base case
 | 
						|
	; Compare input parameter with 1
 | 
						|
	CMP R1, #1                        ; Compare R1 with 1
 | 
						|
 | 
						|
	; If R1 <= 1, branch to base_case
 | 
						|
	BLE base_case                     ; If R1 <= 1, return 1
 | 
						|
 | 
						|
	; Step 2: Recursive case - prepare for recursive call
 | 
						|
	; Save current R1 and LR (return address) on the stack
 | 
						|
	PUSH{R1, LR}                      ; Push R1 and LR onto stack
 | 
						|
 | 
						|
	; Decrement n for recursive call: R1 = R1 - 1
 | 
						|
	SUB R1, R1, #1                    ; R1 = R1 - 1
 | 
						|
 | 
						|
	; Recursive call to factorial function
 | 
						|
	BL fact                           ; Call fact(R1-1), result in R0
 | 
						|
 | 
						|
	; Step 3: Return from recursion - multiply result
 | 
						|
	; Restore saved R1 (original n) and LR from stack
 | 
						|
	POP{R2, LR}                       ; Pop LR and original R1 into R2
 | 
						|
 | 
						|
	; Multiply current result (R0) by original n (R2)
 | 
						|
	; R0 = R0 * R2 = factorial(n-1) * n
 | 
						|
	MUL R0, R0, R2                    ; R0 = R0 * R2
 | 
						|
 | 
						|
	; Return from function (branch to address in LR)
 | 
						|
	BX LR                             ; Return to caller
 | 
						|
 | 
						|
; ========================================================================================
 | 
						|
; base_case - Base case handler for factorial
 | 
						|
; ========================================================================================
 | 
						|
; When n <= 1, factorial = 1
 | 
						|
; Returns: R0 = 1
 | 
						|
 | 
						|
base_case
 | 
						|
	; Set return value to 1 (base case for factorial)
 | 
						|
	MOV R0, #1                        ; R0 = 1 (factorial of 0 or 1 is 1)
 | 
						|
 | 
						|
	; Return from function
 | 
						|
	BX LR                             ; Return to caller
 | 
						|
 | 
						|
; ========================================================================================
 | 
						|
; Execution Example:
 | 
						|
; ========================================================================================
 | 
						|
; Calculating factorial(5):
 | 
						|
; fact(5) -> calls fact(4) -> calls fact(3) -> calls fact(2) -> calls fact(1)
 | 
						|
; fact(1) returns 1
 | 
						|
; fact(2) returns 2 * 1 = 2
 | 
						|
; fact(3) returns 3 * 2 = 6
 | 
						|
; fact(4) returns 4 * 6 = 24
 | 
						|
; fact(5) returns 5 * 24 = 120
 | 
						|
; Final result: 120 is stored at memory location 0x10001000
 | 
						|
 | 
						|
	END                               ; End of the assembly program |