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 |