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. Perform manual division by 10 using repeated subtraction ; b. The remainder (R2) is the current BCD digit (0-9) ; c. The quotient (R3) becomes the input for the next iteration ; d. Multiply digit by position value and add to BCD result ; e. Shift position multiplier left by 4 bits for next digit ; 6. This version uses software division instead of hardware UDIV instruction 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 current value for division (copy R1 to R2) MOV R2, R1 ; R2 = R1 (dividend for this iteration) ; Initialize quotient accumulator to 0 MOV R3, #0 ; R3 = 0 (quotient accumulator) ; Step 4: Manual division by repeated subtraction DIV_LOOP ; Compare dividend with divisor (10) CMP R2, #10 ; Compare R2 with 10 ; If dividend < 10, division is complete BLT DIV_DONE ; Branch if R2 < 10 ; Subtract 10 from dividend (equivalent to R2 = R2 - 10) SUB R2, R2, #10 ; R2 = R2 - 10 ; Increment quotient (equivalent to quotient = quotient + 1) ADD R3, R3, #1 ; R3 = R3 + 1 ; Continue division loop B DIV_LOOP ; Branch back to DIV_LOOP ; Step 5: Division complete - R2 = remainder (0-9), R3 = quotient DIV_DONE ; Multiply the BCD digit (remainder) by its position value ; R8 = R2 * R11 = digit * position_multiplier MUL R8, R2, 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, 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 6: 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 using manual division by repeated subtraction. ; For value 69: ; First iteration: 69 / 10 = 6 (quotient) with remainder 9 ; Second iteration: 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 END ; End of the assembly program