comm
This commit is contained in:
parent
c37a788cbd
commit
dbabb956d5
16 changed files with 1319 additions and 426 deletions
|
@ -1,38 +1,100 @@
|
|||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
__Vectors
|
||||
DCD 0x10001000
|
||||
DCD Reset_Handler
|
||||
ALIGN
|
||||
|
||||
AREA MYCODE, CODE, READONLY
|
||||
ENTRY
|
||||
EXPORT Reset_Handler
|
||||
; ========================================================================================
|
||||
; ASCIItoHEX.asm - ASCII Hexadecimal String to 32-bit Hexadecimal Conversion
|
||||
; ========================================================================================
|
||||
; This program converts an ASCII string representing hexadecimal digits into a
|
||||
; 32-bit hexadecimal value. It processes each ASCII character, converts it to
|
||||
; its corresponding 4-bit hexadecimal value, and builds the final 32-bit result
|
||||
; by shifting and ORing each nibble into place.
|
||||
|
||||
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 pointers to source ASCII string and destination for result
|
||||
; 2. Initialize result accumulator (R1) to 0
|
||||
; 3. Process 8 characters (for 32-bit result) in a loop
|
||||
; 4. For each character:
|
||||
; a. Load ASCII character (byte)
|
||||
; b. Check if it's A-F (greater than '9')
|
||||
; c. Convert ASCII digit to 4-bit hexadecimal value
|
||||
; d. Shift current result left by 4 bits
|
||||
; e. OR the new nibble into the result
|
||||
; 5. Store the final 32-bit hexadecimal value
|
||||
|
||||
Reset_Handler
|
||||
LDR R0, =SRC
|
||||
LDR R3, =DST
|
||||
MOV R1, #0
|
||||
MOV R10, #8
|
||||
|
||||
; Step 1: Initialize pointers and variables
|
||||
; R0 points to the ASCII string source
|
||||
LDR R0, =SRC ; R0 = address of ASCII string
|
||||
|
||||
; R3 points to the destination for the result
|
||||
LDR R3, =DST ; R3 = address of result storage
|
||||
|
||||
; Initialize result accumulator to 0
|
||||
MOV R1, #0 ; R1 = 0 (will hold the final 32-bit result)
|
||||
|
||||
; Set loop counter for 8 characters (8 nibbles = 32 bits)
|
||||
MOV R10, #8 ; R10 = 8 (number of characters to process)
|
||||
|
||||
; Step 2: Main conversion loop
|
||||
UP
|
||||
LDRB R2, [R0], #1
|
||||
CMP R1, #'9'
|
||||
BCC DOWN
|
||||
SUB R2, #7
|
||||
|
||||
; Load the next ASCII character (byte) from the string
|
||||
; Post-increment addressing advances R0 to next character
|
||||
LDRB R2, [R0], #1 ; Load byte from [R0] into R2, then R0 = R0 + 1
|
||||
|
||||
; Check if the character is a letter (A-F) or digit (0-9)
|
||||
; Compare with '9' (ASCII 57) - if R2 <= '9', it's a digit
|
||||
CMP R1, #'9' ; Compare R1 with ASCII '9' (Note: should be CMP R2, #'9')
|
||||
BCC DOWN ; If R2 < '9', branch to DOWN (digit 0-9)
|
||||
|
||||
; Handle A-F characters (subtract 7 to convert A-F to 10-15)
|
||||
SUB R2, #7 ; R2 = R2 - 7 (converts 'A' to 10, 'B' to 11, etc.)
|
||||
|
||||
DOWN
|
||||
SUB R2, #0x30
|
||||
LSL R1, #4
|
||||
ORR R1, R1, R2
|
||||
SUBS R10, #1
|
||||
BNE UP
|
||||
; Convert ASCII digit to actual hexadecimal value
|
||||
; Subtract ASCII '0' (0x30) to convert '0'-'9' to 0-9
|
||||
SUB R2, #0x30 ; R2 = R2 - 0x30 (ASCII to numeric conversion)
|
||||
|
||||
STR R1, [R3]
|
||||
SRC DCB "12AB34CF"
|
||||
|
||||
AREA mydata, DATA, READWRITE
|
||||
; Shift the current result left by 4 bits to make room for new nibble
|
||||
LSL R1, #4 ; R1 = R1 << 4 (shift left by 4 bits)
|
||||
|
||||
DST DCD 0
|
||||
; OR the new 4-bit value into the result
|
||||
ORR R1, R1, R2 ; R1 = R1 | R2 (insert new nibble)
|
||||
|
||||
END
|
||||
; Decrement loop counter and set condition flags
|
||||
SUBS R10, #1 ; R10 = R10 - 1, set flags for branch condition
|
||||
|
||||
; Branch back to UP if counter is not zero
|
||||
BNE UP ; If R10 != 0, continue loop
|
||||
|
||||
; Step 3: Store the final result
|
||||
; Store the 32-bit hexadecimal value to destination
|
||||
STR R1, [R3] ; Store R1 (final result) to [R3]
|
||||
|
||||
; ========================================================================================
|
||||
; Data Section - ASCII Source String and Result Storage
|
||||
; ========================================================================================
|
||||
; SRC contains ASCII string "12AB34CF" (8 characters)
|
||||
; Each character represents a hexadecimal digit:
|
||||
; '1','2' -> digits 0-9
|
||||
; 'A','B','C','F' -> digits 10-15
|
||||
; The string will be converted to: 0x12AB34CF
|
||||
SRC DCB "12AB34CF" ; ASCII string to be converted
|
||||
|
||||
AREA mydata, DATA, READWRITE ; Define a read-write data section
|
||||
|
||||
; DST - Storage for the final 32-bit hexadecimal result
|
||||
DST DCD 0 ; Space for the converted result
|
||||
|
||||
END ; End of the assembly program
|
|
@ -1,35 +1,93 @@
|
|||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
__Vectors
|
||||
DCD 0x10001000
|
||||
DCD Reset_Handler
|
||||
ALIGN
|
||||
|
||||
AREA MYCODE, CODE, READONLY
|
||||
ENTRY
|
||||
EXPORT Reset_Handler
|
||||
; ========================================================================================
|
||||
; BCDtoHEX.asm - Binary Coded Decimal to Hexadecimal Conversion
|
||||
; ========================================================================================
|
||||
; This program converts a BCD (Binary Coded Decimal) value to its equivalent
|
||||
; hexadecimal representation. BCD stores each decimal digit in 4 bits, so a
|
||||
; byte can represent two decimal digits (00-99). The program extracts each
|
||||
; BCD digit and converts the entire BCD number to its decimal equivalent.
|
||||
|
||||
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. Load the BCD value from memory (each byte contains two BCD digits)
|
||||
; 2. Initialize multiplier (R2) to 1 for units place
|
||||
; 3. Process 3 iterations (for 3 BCD digits in the example)
|
||||
; 4. In each iteration:
|
||||
; a. Extract lowest 4 bits (current BCD digit) using AND
|
||||
; b. Multiply digit by current place value and add to result
|
||||
; c. Shift BCD value right by 4 bits to get next digit
|
||||
; d. Multiply place value by 10 for next iteration
|
||||
; 5. Result (R4) contains the decimal equivalent of the BCD number
|
||||
|
||||
Reset_Handler
|
||||
LDR R0, =SRR
|
||||
MOV R10, #3
|
||||
LDR R1, [R0]
|
||||
MOV R2, #1
|
||||
|
||||
UP
|
||||
AND R3, R1, #0x0F
|
||||
MLA R4, R2, R3, R4
|
||||
LSR R1, #4
|
||||
MOV R5, #0x0A
|
||||
MUL R2, R5
|
||||
SUBS R10, #1
|
||||
BNE UP
|
||||
|
||||
STOP
|
||||
B STOP
|
||||
|
||||
SRR DCD 0x45
|
||||
; Step 1: Initialize source pointer and load BCD value
|
||||
; R0 points to the BCD value in memory
|
||||
LDR R0, =SRR ; R0 = address of BCD value
|
||||
|
||||
AREA mydata, DATA, READWRITE
|
||||
SRC DCD 0x45
|
||||
|
||||
END
|
||||
; Set loop counter for 3 digits (processing 12 bits of the 32-bit value)
|
||||
MOV R10, #3 ; R10 = 3 (number of BCD digits to process)
|
||||
|
||||
; Load the BCD value into R1
|
||||
LDR R1, [R0] ; R1 = BCD value (e.g., 0x45 = 0100 0101 BCD)
|
||||
|
||||
; Initialize multiplier for place value (1 for units, 10 for tens, etc.)
|
||||
MOV R2, #1 ; R2 = 1 (initial place value multiplier)
|
||||
|
||||
; Step 2: Main BCD to decimal conversion loop
|
||||
UP
|
||||
; Extract the lowest 4 bits (current BCD digit 0-9)
|
||||
; AND with 0x0F isolates the least significant nibble
|
||||
AND R3, R1, #0x0F ; R3 = R1 & 0x0F (extract BCD digit)
|
||||
|
||||
; Multiply digit by place value and accumulate result
|
||||
; MLA (Multiply Accumulate) computes: R4 = R2 * R3 + R4
|
||||
; This adds the current digit's contribution to the total
|
||||
MLA R4, R2, R3, R4 ; R4 = (R2 * R3) + R4
|
||||
|
||||
; Shift BCD value right by 4 bits to access next digit
|
||||
LSR R1, #4 ; R1 = R1 >> 4 (move to next BCD digit)
|
||||
|
||||
; Prepare multiplier for next place value (multiply by 10)
|
||||
; This sets up R2 for tens, hundreds, etc. in subsequent iterations
|
||||
MOV R5, #0x0A ; R5 = 10 (decimal)
|
||||
MUL R2, R5 ; R2 = R2 * 10 (update place value)
|
||||
|
||||
; Decrement loop counter and set condition flags
|
||||
SUBS R10, #1 ; R10 = R10 - 1, set flags for branch condition
|
||||
|
||||
; Branch back to UP if counter is not zero
|
||||
BNE UP ; If R10 != 0, continue loop
|
||||
|
||||
; Step 3: Program termination
|
||||
; Note: The result is stored in R4 but never saved to memory
|
||||
STOP
|
||||
B STOP ; Branch to STOP label (infinite loop)
|
||||
|
||||
; ========================================================================================
|
||||
; Data Section - BCD Source Value
|
||||
; ========================================================================================
|
||||
; SRR contains a BCD value: 0x45
|
||||
; In BCD format: 0100 0101 = digits 4 and 5
|
||||
; Decimal equivalent: 4*10 + 5 = 45
|
||||
; The program converts this to decimal 45 (though result is never stored)
|
||||
SRR DCD 0x45 ; BCD value to be converted
|
||||
|
||||
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
|
|
@ -1,41 +1,92 @@
|
|||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
__Vectors
|
||||
DCD 0x10001000
|
||||
DCD Reset_Handler
|
||||
ALIGN
|
||||
; ========================================================================================
|
||||
; 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 MYCODE, CODE, READONLY
|
||||
ENTRY
|
||||
EXPORT Reset_Handler
|
||||
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
|
||||
MOV r0, #48
|
||||
MOV r1, #18
|
||||
; 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
|
||||
CMP r0, r1
|
||||
BEQ GCD_Done
|
||||
BGT GT_A_B
|
||||
SUB r1, r1, r0
|
||||
B 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
|
||||
B GCD_Loop
|
||||
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
|
||||
LDR r2, =result
|
||||
STR r0, [r2]
|
||||
; 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
|
||||
B LoopForever ; Branch to LoopForever (infinite loop)
|
||||
|
||||
ALIGN
|
||||
ALIGN ; Ensure proper alignment for data section
|
||||
|
||||
AREA MYDATA, DATA, READWRITE
|
||||
numA DCD 48
|
||||
numB DCD 18
|
||||
result DCD 0
|
||||
AREA MYDATA, DATA, READWRITE ; Define a read-write data section
|
||||
|
||||
END
|
||||
; ========================================================================================
|
||||
; 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
|
|
@ -1,37 +1,102 @@
|
|||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
__Vectors
|
||||
DCD 0x10001000
|
||||
DCD Reset_Handler
|
||||
ALIGN
|
||||
|
||||
AREA MYCODE, CODE, READONLY
|
||||
ENTRY
|
||||
EXPORT Reset_Handler
|
||||
; ========================================================================================
|
||||
; HEXtoASCII.asm - 32-bit Hexadecimal to ASCII String Conversion
|
||||
; ========================================================================================
|
||||
; This program converts a 32-bit hexadecimal value into its ASCII string
|
||||
; representation. Each 4-bit nibble of the hexadecimal value is converted
|
||||
; to its corresponding ASCII character ('0'-'9' for digits, 'A'-'F' for
|
||||
; values 10-15). The result is stored as a sequence of ASCII bytes.
|
||||
|
||||
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. Load the 32-bit hexadecimal value from memory
|
||||
; 2. Initialize destination pointer for ASCII string storage
|
||||
; 3. Set loop counter for 8 nibbles (32 bits = 8 nibbles)
|
||||
; 4. Process each nibble from least significant to most significant:
|
||||
; a. Extract lowest 4 bits using AND with 0x0F
|
||||
; b. Check if digit (0-9) or letter (A-F)
|
||||
; c. Convert to ASCII: add 0x30 for digits, add 0x37 for A-F
|
||||
; d. Store ASCII character to destination array
|
||||
; e. Shift original value right by 4 bits for next nibble
|
||||
; 5. Result is an ASCII string representing the hexadecimal value
|
||||
|
||||
Reset_Handler
|
||||
LDR R0, =SRC
|
||||
LDR R1, [R0]
|
||||
LDR R3, =DST
|
||||
MOV R10, #8
|
||||
|
||||
; Step 1: Initialize source and destination pointers
|
||||
; R0 points to the 32-bit hexadecimal value
|
||||
LDR R0, =SRC ; R0 = address of hexadecimal value
|
||||
|
||||
; Load the hexadecimal value into R1
|
||||
LDR R1, [R0] ; R1 = 32-bit hexadecimal value (e.g., 0x12AB34CF)
|
||||
|
||||
; R3 points to the destination for ASCII string
|
||||
LDR R3, =DST ; R3 = address of ASCII string storage
|
||||
|
||||
; Step 2: Initialize loop counter
|
||||
; Process 8 nibbles (32 bits / 4 bits per nibble = 8 nibbles)
|
||||
MOV R10, #8 ; R10 = 8 (number of nibbles to process)
|
||||
|
||||
; Step 3: Main conversion loop - process each nibble
|
||||
UP
|
||||
AND R2, R1, #0x0F
|
||||
CMP R2, #09
|
||||
BCC DOWN
|
||||
ADD R2, #7
|
||||
|
||||
; Extract the lowest 4 bits (current nibble 0-15)
|
||||
; AND with 0x0F isolates the least significant nibble
|
||||
AND R2, R1, #0x0F ; R2 = R1 & 0x0F (extract nibble 0-15)
|
||||
|
||||
; Check if the nibble represents a digit (0-9) or letter (A-F)
|
||||
; Compare with 9 (decimal) - values 0-9 are digits, 10-15 are A-F
|
||||
CMP R2, #09 ; Compare R2 with 9
|
||||
BCC DOWN ; If R2 <= 9, branch to DOWN (digit)
|
||||
|
||||
; Handle A-F characters (add 7 to skip punctuation in ASCII table)
|
||||
; ASCII: '0'-'9' = 0x30-0x39, 'A'-'F' = 0x41-0x46
|
||||
; For values 10-15: add 0x30 + 7 = 0x37 to get 'A'-'F'
|
||||
ADD R2, #7 ; R2 = R2 + 7 (adjust for A-F range)
|
||||
|
||||
; Convert nibble to ASCII character
|
||||
DOWN
|
||||
ADD R2, #0x30
|
||||
STR R2, [R3], #4
|
||||
LSR R1, #4
|
||||
SUBS R10, #1
|
||||
BNE UP
|
||||
|
||||
SRC DCD 0x12AB34CF
|
||||
|
||||
AREA mydata, DATA, READWRITE
|
||||
; Add ASCII '0' (0x30) to convert nibble to ASCII digit/letter
|
||||
; For digits 0-9: 0-9 + 0x30 = 0x30-0x39 ('0'-'9')
|
||||
; For A-F: 10-15 + 0x37 = 0x41-0x46 ('A'-'F')
|
||||
ADD R2, #0x30 ; R2 = R2 + 0x30 (convert to ASCII)
|
||||
|
||||
DST DCD 0
|
||||
; Store the ASCII character to destination array
|
||||
; Post-increment addressing advances R3 to next position
|
||||
STR R2, [R3], #4 ; Store ASCII char and advance R3 by 4 bytes
|
||||
|
||||
END
|
||||
; Shift the original value right by 4 bits to process next nibble
|
||||
LSR R1, #4 ; R1 = R1 >> 4 (move to next nibble)
|
||||
|
||||
; Decrement loop counter and set condition flags
|
||||
SUBS R10, #1 ; R10 = R10 - 1, set flags for branch condition
|
||||
|
||||
; Branch back to UP if counter is not zero
|
||||
BNE UP ; If R10 != 0, continue loop
|
||||
|
||||
; ========================================================================================
|
||||
; Data Section - Hexadecimal Source Value and ASCII String Storage
|
||||
; ========================================================================================
|
||||
; SRC contains the 32-bit hexadecimal value: 0x12AB34CF
|
||||
; This will be converted to ASCII string: "12AB34CF"
|
||||
; Each nibble is converted to its ASCII equivalent:
|
||||
; 0x1 -> '1', 0x2 -> '2', 0xA -> 'A', 0xB -> 'B', 0x3 -> '3', 0x4 -> '4', 0xC -> 'C', 0xF -> 'F'
|
||||
SRC DCD 0x12AB34CF ; 32-bit hexadecimal value to be converted
|
||||
|
||||
AREA mydata, DATA, READWRITE ; Define a read-write data section
|
||||
|
||||
; DST - Storage for the ASCII string result (8 characters, 32 bytes)
|
||||
; Each ASCII character is stored as a word (4 bytes) for easier access
|
||||
DST DCD 0 ; Space for ASCII string (will expand as needed)
|
||||
|
||||
END ; End of the assembly program
|
|
@ -9,31 +9,97 @@ __Vectors
|
|||
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
|
||||
LDR R0, =SRR
|
||||
LDR R1, [R0]
|
||||
MOV R4, #0
|
||||
MOV R11, #1
|
||||
MOV R10, #3
|
||||
; 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
|
||||
MOV R5, #10
|
||||
UDIV R3, R1, R5
|
||||
MUL R6, R3, R5
|
||||
SUB R7, R1, R6
|
||||
MUL R8, R7, R11
|
||||
ADD R4, R4, R8
|
||||
LSL R11, R11, #4
|
||||
MOV R1, R3
|
||||
SUBS R10, #1
|
||||
BNE 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
|
||||
|
||||
SRR DCD 0x45
|
||||
B STOP ; Branch to STOP label (infinite loop)
|
||||
|
||||
AREA mydata, DATA, READWRITE
|
||||
SRC DCD 0x45
|
||||
|
||||
END
|
||||
; ========================================================================================
|
||||
; 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
|
|
@ -9,35 +9,104 @@ __Vectors
|
|||
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
|
||||
LDR R0, =SRR
|
||||
LDR R1, [R0]
|
||||
MOV R4, #0
|
||||
MOV R11, #1
|
||||
MOV R10, #3
|
||||
; 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
|
||||
MOV R2, R1
|
||||
MOV R3, #0
|
||||
|
||||
; 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
|
||||
CMP R2, #10
|
||||
BLT DIV_DONE
|
||||
SUB R2, R2, #10
|
||||
ADD R3, R3, #1
|
||||
B 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
|
||||
MUL R8, R2, R11
|
||||
ADD R4, R4, R8
|
||||
LSL R11, R11, #4
|
||||
MOV R1, R3
|
||||
SUBS R10, R10, #1
|
||||
BNE LOOP
|
||||
; 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
|
||||
B STOP ; Branch to STOP label (infinite loop)
|
||||
|
||||
SRR DCD 0x45
|
||||
; ========================================================================================
|
||||
; 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 ; End of the assembly program
|
Loading…
Add table
Add a link
Reference in a new issue