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

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