MIT-Curricular/ES/Lab/LAB4/GCD.asm
2025-08-28 10:11:40 +05:30

92 lines
No EOL
4.4 KiB
NASM

; ========================================================================================
; GCD.asm - Greatest Common Divisor Using Euclidean Algorithm
; ========================================================================================
; This program implements the Euclidean algorithm to find the Greatest Common
; Divisor (GCD) of two numbers. The Euclidean algorithm is based on the principle
; that GCD(a, b) = GCD(b, a mod b), and it repeats this process until b = 0.
; When b = 0, the GCD is the value of a.
AREA RESET, DATA, READONLY ; Define a read-only data section for the vector table
EXPORT __Vectors ; Export the vector table for external linking
__Vectors ; Start of the vector table
DCD 0x10001000 ; Stack pointer initial value (points to top of stack)
DCD Reset_Handler ; Address of the reset handler (program entry point)
ALIGN ; Ensure proper alignment for the next section
AREA MYCODE, CODE, READONLY ; Define the code section as read-only
ENTRY ; Mark the entry point of the program
EXPORT Reset_Handler ; Export the reset handler function
; ========================================================================================
; Reset_Handler - Main program execution
; ========================================================================================
; Algorithm Overview:
; 1. Initialize two numbers in registers R0 and R1 (48 and 18 in this example)
; 2. Enter the Euclidean algorithm loop:
; a. Compare the two numbers
; b. If equal, GCD is found (algorithm complete)
; c. If R0 > R1, subtract R1 from R0 (replace larger with difference)
; d. If R0 < R1, subtract R0 from R1 (replace larger with difference)
; e. Repeat until both numbers are equal
; 3. Store the GCD result to memory
; 4. Enter infinite loop for program termination
Reset_Handler
; Step 1: Initialize the two numbers for GCD calculation
; R0 and R1 hold the two numbers to find GCD of
MOV r0, #48 ; R0 = 48 (first number)
MOV r1, #18 ; R1 = 18 (second number)
; Step 2: Main Euclidean algorithm loop
GCD_Loop
; Compare the two numbers to determine which is larger
CMP r0, r1 ; Compare R0 and R1, set condition flags
; If R0 == R1, we have found the GCD
BEQ GCD_Done ; Branch to GCD_Done if R0 == R1
; If R0 > R1 (GT condition), subtract R1 from R0
BGT GT_A_B ; Branch to GT_A_B if R0 > R1
; If R0 < R1, subtract R0 from R1 (replace larger with difference)
SUB r1, r1, r0 ; R1 = R1 - R0 (R1 was larger, now smaller)
B GCD_Loop ; Branch back to GCD_Loop
; Handle case where R0 > R1
GT_A_B
SUB r0, r0, r1 ; R0 = R0 - R1 (R0 was larger, now smaller)
B GCD_Loop ; Branch back to GCD_Loop
; Step 3: GCD calculation complete
; When we reach here, R0 == R1 and contains the GCD
GCD_Done
; Load address of result storage into R2
LDR r2, =result ; R2 = address of result storage
; Store the GCD (in R0) to memory
STR r0, [r2] ; Store GCD value to [R2]
; Step 4: Program termination
; Enter infinite loop to stop program execution
LoopForever
B LoopForever ; Branch to LoopForever (infinite loop)
ALIGN ; Ensure proper alignment for data section
AREA MYDATA, DATA, READWRITE ; Define a read-write data section
; ========================================================================================
; Data Section - Input Numbers and Result Storage
; ========================================================================================
; numA: First number for GCD calculation (48 in this example)
; numB: Second number for GCD calculation (18 in this example)
; GCD(48, 18) = 6, as calculated by the Euclidean algorithm:
; GCD(48, 18) -> GCD(18, 48-18=30) -> GCD(30, 18) -> GCD(18, 30-18=12)
; -> GCD(12, 18) -> GCD(18, 12) -> GCD(12, 18-12=6) -> GCD(6, 12)
; -> GCD(12, 6) -> GCD(6, 12-6=0) -> GCD(6, 0) = 6
numA DCD 48 ; First number for GCD
numB DCD 18 ; Second number for GCD
result DCD 0 ; Storage for the GCD result
END ; End of the assembly program