Description of the code and its purpose : This MIPS assembly program reads a string of hexadecimal pairs separated by a dollar sign (‘$’), validates the input, converts the hexadecimal pairs to numerical values, and then sorts and prints the numbers as both signed and unsigned integers in a descending order.
the problem : I am facing two primary issues. Firstly, in the unsigned representation, the value zero is not displayed, and it needs to be. Secondly, in the signed representation, there is a missing value that needs to be accounted for.
.data
array: .space 37
array_len: .word 0
newline: .asciiz "n"
space: .asciiz " "
prompt: .asciiz "Enter a string of hexadecimal pairs separated by $: "
wrong_input: .asciiz "Wrong input. Please enter again: "
stringhex: .space 37
NUM: .space 12
signed: .space 12
unsigned: .space 12
.text
.globl main
main:
la $a0, prompt # Load address of prompt message
li $v0, 4 # Syscall code for print_string
syscall # Print prompt message
la $a0, stringhex # Load address of stringhex array
li $a1, 37 # Maximum number of characters to read
li $v0, 8 # Syscall code for read_string
syscall # Read the input string
validate_input:
la $a0, stringhex # Load address of stringhex array
jal is_valid # Call is_valid procedure
move $t1, $v0 # Move return value to $t1
beq $t1, 0, invalid_input # If input is invalid, go to invalid_input
la $a0, stringhex # Load address of stringhex array
la $a1, NUM # Load address of NUM array
move $a2, $t1 # Move number of valid pairs to $a2
jal convert # Call convert procedure
# Copy NUM to signed
la $t0, NUM # Load address of NUM array
la $t1, signed # Load address of signed array
li $t2, 0 # Initialize index
copy_loop:
bge $t2, $a2, sort_signed # If index >= number of pairs, exit loop
lb $t3, 0($t0) # Load byte from NUM
sb $t3, 0($t1) # Store byte in signed
addi $t0, $t0, 1 # Increment NUM pointer
addi $t1, $t1, 1 # Increment signed pointer
addi $t2, $t2, 1 # Increment index
j copy_loop # Repeat loop
sort_signed:
la $t0, signed # Load address of signed array
move $t1, $a2 # Move number of valid pairs to $t1
li $t2, 0 # Set outer loop index to 0
outer_loop:
bge $t2, $t1, done # If outer loop index >= array length, exit outer loop
li $t3, 0 # Set inner loop index to 0
inner_loop:
bge $t3, $t1, next_outer # If inner loop index >= array length, exit inner loop
sll $t4, $t3, 0 # Calculate offset (index * 1)
add $t4, $t0, $t4 # Address of signed[t3]
lb $t5, 0($t4) # Load byte of signed[t3] into $t5
lb $t6, 1($t4) # Load byte of signed[t3 + 1] into $t6
bge $t5, $t6, skip_swap # If signed[t3] >= signed[t3 + 1], skip swap
# Swap bytes
sb $t6, 0($t4)
sb $t5, 1($t4)
skip_swap:
addi $t3, $t3, 1 # Increment inner loop index by 1
j inner_loop # Jump back to inner loop
next_outer:
addi $t2, $t2, 1 # Increment outer loop index by 1
j outer_loop # Jump back to outer loop
done:
li $t2, 0 # Set index to 0
print_signed:
bge $t2, $t1, print_unsigned # If index >= array length, exit print loop
add $t4, $t0, $t2 # Address of signed[index]
lb $a0, 0($t4) # Load byte of signed into $a0
li $v0, 1 # Syscall code for print_int
syscall # Print the byte as an integer
addi $t2, $t2, 1 # Increment index by 1
blt $t2, $t1, print_space # If index < array length, print space
print_space:
li $v0, 4 # Load syscall code for print_string
la $a0, space # Load address of space string
syscall # Print space
j print_signed # Jump back to print loop
print_unsigned:
# Print newline
li $v0, 4 # Syscall code for print_string
la $a0, newline # Load address of newline string
syscall # Print newline
# Copy NUM to unsigned
la $t0, NUM # Load address of NUM array
la $t1, unsigned # Load address of unsigned array
li $t2, 0 # Initialize index
copy_loop2:
bge $t2, $a2, sort_unsigned # If index >= number of pairs, exit loop
lb $t3, 0($t0) # Load byte from NUM
sb $t3, 0($t1) # Store byte in unsigned
addi $t0, $t0, 1 # Increment NUM pointer
addi $t1, $t1, 1 # Increment unsigned pointer
addi $t2, $t2, 1 # Increment index
j copy_loop2 # Repeat loop
sort_unsigned:
la $t0, unsigned # Load address of unsigned array
move $t1, $a2 # Move number of valid pairs to $t1
li $t2, 0 # Set outer loop index to 0
outer_loop2:
bge $t2, $t1, done2 # If outer loop index >= array length, exit outer loop
li $t3, 0 # Set inner loop index to 0
inner_loop2:
bge $t3, $t1, next_outer2 # If inner loop index >= array length, exit inner loop
sll $t4, $t3, 0 # Calculate offset (index * 1)
add $t4, $t0, $t4 # Address of unsigned[t3]
lbu $t5, 0($t4) # Load byte of unsigned[t3] into $t5
lbu $t6, 1($t4) # Load byte of unsigned[t3 + 1] into $t6
bge $t5, $t6, skip_swap2 # If unsigned[t3] >= unsigned[t3 + 1], skip swap
# Swap bytes
sb $t6, 0($t4)
sb $t5, 1($t4)
skip_swap2:
addi $t3, $t3, 1 # Increment inner loop index by 1
j inner_loop2 # Jump back to inner loop
next_outer2:
addi $t2, $t2, 1 # Increment outer loop index by 1
j outer_loop2 # Jump back to outer loop
done2:
li $t2, 0 # Set index to 0
print_unsigned2:
bge $t2, $t1, end # If index >= array length, exit print loop
add $t4, $t0, $t2 # Address of unsigned[index]
lbu $a0, 0($t4) # Load byte of unsigned into $a0
li $v0, 1 # Syscall code for print_int
syscall # Print the byte as an integer
addi $t2, $t2, 1 # Increment index by 1
blt $t2, $t1, print_space2 # If index < array length, print space
print_space2:
li $v0, 4 # Load syscall code for print_string
la $a0, space # Load address of space string
syscall # Print space
j print_unsigned2 # Jump back to print loop
end:
# Print newline
li $v0, 4 # Syscall code for print_string
la $a0, newline # Load address of newline string
syscall # Print newline
# Exit the program
li $v0, 10 # Load syscall code for exit
syscall # Exit program
invalid_input:
la $a0, wrong_input # Load address of wrong input message
li $v0, 4 # Syscall code for print_string
syscall # Print wrong input message
j main # Jump back to main to re-enter the string
# Procedure to validate input
is_valid:
addi $sp, $sp, -8 # Allocate space on stack
sw $ra, 0($sp) # Save return address
sw $a0, 4($sp) # Save $a0
li $t0, 0 # Initialize counter for pairs
li $t1, 0 # Initialize index
li $t9, 0 # Initialize flag to check for two hex digits before $
la $t2, stringhex # Load address of stringhex array
check_loop:
lb $t3, 0($t2) # Load current character
beq $t3, 0, valid # If null terminator, input is valid
beq $t3, 10, valid # If newline, input is valid
li $t4, 36 # Maximum length of the input
bge $t1, $t4, invalid_char # If index >= 36, input is invalid
lb $t3, 0($t2) # Reload current character
li $t4, 36 # ASCII '$'
beq $t3, $t4, check_separator
# Check for valid hex character
li $t4, 48 # ASCII '0'
li $t5, 57 # ASCII '9'
blt $t3, $t4, invalid_char
bgt $t3, $t5, check_hex_alpha
j check_next
check_hex_alpha:
li $t4, 65 # ASCII 'A'
li $t5, 70 # ASCII 'F'
blt $t3, $t4, invalid_char
bgt $t3, $t5, invalid_char
check_next:
addi $t9, $t9, 1 # Increment hex digit counter
addi $t1, $t1, 1 # Increment index
addi $t2, $t2, 1 # Move to next character
j check_loop # Repeat loop
check_separator:
# Check if previous character was also $
lb $t4, -1($t2)
li $t5, 36
beq $t4, $t5, invalid_char
# Check if there are exactly two hex digits before $
bne $t9, 2, invalid_char
addi $t0, $t0, 1 # Increment pair counter
li $t9, 0 # Reset hex digit counter
addi $t1, $t1, 1 # Increment index
addi $t2, $t2, 1 # Move to next character
j check_loop # Repeat loop
invalid_char:
li $v0, 0 # Return 0 for invalid input
j end_validation
valid:
move $v0, $t0 # Return the number of valid pairs
end_validation:
lw $ra, 0($sp) # Restore return address
lw $a0, 4($sp) # Restore $a0
addi $sp, $sp, 8 # Deallocate space on stack
jr $ra # Return from procedure
# Procedure to convert hex pairs to numerical values
convert:
addi $sp, $sp, -8 # Allocate space on stack
sw $ra, 0($sp) # Save return address
sw $a0, 4($sp) # Save $a0
move $t0, $a0 # Address of stringhex array
move $t1, $a1 # Address of NUM array
move $t2, $a2 # Number of valid pairs
li $t3, 0 # Initialize index for stringhex
li $t4, 0 # Initialize index for NUM
convert_loop:
bge $t4, $t2, convert_done # If NUM index >= number of pairs, exit loop
lb $t5, 0($t0) # Load first hex character
lb $t6, 1($t0) # Load second hex character
# Convert first hex character to numerical value
li $t7, 48 # ASCII '0'
li $t8, 57 # ASCII '9'
blt $t5, $t7, convert_alpha1
bgt $t5, $t8, convert_alpha1
sub $t5, $t5, $t7 # Convert '0'-'9' to 0-9
j convert_next1
convert_alpha1:
li $t7, 65 # ASCII 'A'
li $t8, 70 # ASCII 'F'
sub $t5, $t5, 55 # Convert 'A'-'F' to 10-15
convert_next1:
sll $t5, $t5, 4 # Shift left by 4 bits (equivalent to multiplying by 16)
# Convert second hex character to numerical value
li $t7, 48 # ASCII '0'
li $t8, 57 # ASCII '9'
blt $t6, $t7, convert_alpha2
bgt $t6, $t8, convert_alpha2
sub $t6, $t6, $t7 # Convert '0'-'9' to 0-9
j convert_next2
convert_alpha2:
li $t7, 65 # ASCII 'A'
li $t8, 70 # ASCII 'F'
sub $t6, $t6, 55 # Convert 'A'-'F' to 10-15
convert_next2:
or $t5, $t5, $t6 # Combine the two values
sb $t5, 0($t1) # Store the result in NUM array
addi $t0, $t0, 3 # Move to the next pair in stringhex (skip '$')
addi $t1, $t1, 1 # Move to the next position in NUM
addi $t4, $t4, 1 # Increment NUM index
j convert_loop # Repeat loop
convert_done:
lw $ra, 0($sp) # Restore return address
lw $a0, 4($sp) # Restore $a0
addi $sp, $sp, 8 # Deallocate space on stack
jr $ra # Return from procedure
I have been attempting to resolve these issues for the past three days. I even tried rewriting the program from scratch, but I encountered the same problems. I sought assistance from ChatGPT but was unable to find the correct solution.