105 lines
		
	
	
		
			No EOL
		
	
	
		
			4.3 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			105 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
 | |
| 
 | |
| ; ========================================================================================
 | |
| ; Reset_Handler - Main program execution
 | |
| ; ========================================================================================
 | |
| ; Algorithm Overview:
 | |
| ; 1. Load the hexadecimal value from memory
 | |
| ; 2. Initialize BCD result accumulator (R4) to 0
 | |
| ; 3. Initialize digit position multiplier (R11) to 1 (units place)
 | |
| ; 4. Set loop counter for number of BCD digits to process
 | |
| ; 5. In each iteration:
 | |
| ;    a. Divide current value by 10 to get quotient and remainder
 | |
| ;    b. The remainder is the current BCD digit (0-9)
 | |
| ;    c. Multiply digit by position value and add to BCD result
 | |
| ;    d. Shift position multiplier left by 4 bits for next digit
 | |
| ;    e. Use quotient as input for next iteration
 | |
| ; 6. Result (R4) contains the BCD representation of the original number
 | |
| 
 | |
| Reset_Handler
 | |
| 	; Step 1: Initialize source pointer and load hexadecimal value
 | |
| 	; R0 points to the hexadecimal value in memory
 | |
| 	LDR R0, =SRR                      ; R0 = address of hexadecimal value
 | |
| 
 | |
| 	; Load the hexadecimal value into R1
 | |
| 	LDR R1, [R0]                      ; R1 = hexadecimal value (e.g., 0x45 = 69 decimal)
 | |
| 
 | |
| 	; Step 2: Initialize BCD conversion variables
 | |
| 	; R4 will accumulate the final BCD result
 | |
| 	MOV R4, #0                        ; R4 = 0 (BCD result accumulator)
 | |
| 
 | |
| 	; R11 holds the position multiplier for each BCD digit
 | |
| 	; Starts at 1 for units place, shifts left by 4 bits each iteration
 | |
| 	MOV R11, #1                       ; R11 = 1 (position multiplier)
 | |
| 
 | |
| 	; Set loop counter for 3 BCD digits (maximum for byte values 0-255)
 | |
| 	MOV R10, #3                       ; R10 = 3 (number of BCD digits to process)
 | |
| 
 | |
| 	; Step 3: Main BCD conversion loop
 | |
| LOOP
 | |
| 	; Prepare divisor for decimal division
 | |
| 	MOV R5, #10                       ; R5 = 10 (decimal divisor)
 | |
| 
 | |
| 	; Divide current value by 10 to extract least significant digit
 | |
| 	; UDIV performs unsigned division: R3 = R1 / 10 (quotient)
 | |
| 	UDIV R3, R1, R5                   ; R3 = R1 / 10 (quotient)
 | |
| 
 | |
| 	; Calculate remainder: remainder = dividend - (quotient * divisor)
 | |
| 	; MUL computes: R6 = R3 * R5 = quotient * 10
 | |
| 	MUL R6, R3, R5                    ; R6 = R3 * 10
 | |
| 
 | |
| 	; Calculate remainder: R7 = R1 - R6 = R1 - (quotient * 10)
 | |
| 	SUB R7, R1, R6                    ; R7 = R1 - R6 (remainder, value 0-9)
 | |
| 
 | |
| 	; Multiply the BCD digit by its position value
 | |
| 	; R8 = R7 * R11 = digit * position_multiplier
 | |
| 	MUL R8, R7, R11                   ; R8 = digit * position_value
 | |
| 
 | |
| 	; Add the weighted digit to the BCD result accumulator
 | |
| 	ADD R4, R4, R8                    ; R4 = R4 + R8 (accumulate BCD digit)
 | |
| 
 | |
| 	; Shift position multiplier left by 4 bits for next digit position
 | |
| 	; Units (2^0) -> Tens (2^4) -> Hundreds (2^8) -> Thousands (2^12)
 | |
| 	LSL R11, R11, #4                  ; R11 = R11 << 4 (next position)
 | |
| 
 | |
| 	; Prepare quotient as input for next iteration
 | |
| 	; The quotient becomes the new dividend for the next digit
 | |
| 	MOV R1, R3                        ; R1 = R3 (use quotient for next iteration)
 | |
| 
 | |
| 	; Decrement loop counter and set condition flags
 | |
| 	SUBS R10, #1                      ; R10 = R10 - 1, set flags for branch condition
 | |
| 
 | |
| 	; Branch back to LOOP if counter is not zero
 | |
| 	BNE LOOP                          ; If R10 != 0, continue loop
 | |
| 
 | |
| 	; Step 4: Program termination
 | |
| 	; The BCD result is stored in R4 but never saved to memory
 | |
| STOP
 | |
| 	B STOP                            ; Branch to STOP label (infinite loop)
 | |
| 
 | |
| ; ========================================================================================
 | |
| ; Data Section - Hexadecimal Source Value
 | |
| ; ========================================================================================
 | |
| ; SRR contains the hexadecimal value: 0x45 (69 in decimal)
 | |
| ; This will be converted to BCD format. For value 69:
 | |
| ; 69 / 10 = 6 (quotient) with remainder 9
 | |
| ; 6 / 10 = 0 (quotient) with remainder 6
 | |
| ; Result: BCD = 0x69 (6 in tens place, 9 in units place)
 | |
| ; In BCD: 0110 1001 = 0x69
 | |
| SRR DCD 0x45                         ; Hexadecimal value to be converted to BCD
 | |
| 
 | |
| 	AREA mydata, DATA, READWRITE      ; Define a read-write data section
 | |
| 
 | |
| ; SRC - Additional storage (seems unused in this program)
 | |
| SRC DCD 0x45                         ; Duplicate of SRR (possibly for testing)
 | |
| 
 | |
| 	END                               ; End of the assembly program |