/*
* @topic T0M305 MIPS assembly
* @brief reverse string and string length using MIPS procedure
* reverse the characters in the string
*/
.data
.eqv SERVICE_EXIT 10
.eqv SERVICE_PRINT_INT 1
.eqv READ_STRING_SERVICE 8
.eqv PRINT_STRING_SERVICE 4
.eqv EXIT_PROGRAM_SERVICE 10
.eqv MAX_STRING_SIZE 80
.eqv NEWLINE 0xA # \n
input: .space MAX_STRING_SIZE
msg_length: .asciiz "string length is: "
prompt: .asciiz "enter a string: "
idx_tail: .word 0
idx_front: .word 0
.text
li $v0, PRINT_STRING_SERVICE
la $t0, prompt
add $a0, $t0, $zero
syscall
li $v0, READ_STRING_SERVICE
la $t0, input
add $a0, $t0, $zero
li $a1, MAX_STRING_SIZE
syscall
# find the length of input string:
la $a0, input
jal string_length
# length is ready
# at this point $t3 has the length of input
move $s3, $t3 # preserve the length of input
li $v0, PRINT_STRING_SERVICE
la $t0, msg_length
add $a0, $t0, $zero
syscall
# at this point $a0 has the length of input
li $v0, SERVICE_PRINT_INT
add $a0, $s3, $zero # load $a0
syscall
beqz $s3, exit_the_prog # empty input causes the prog to exit
# reverse characters in the string:
# 0123456789
# abcdef
# | |
# | idx_tail = input.length() - 1
# idx_front = 0
move $t0, $s3 # input.length()
move $t1, $zero # idx_front
addu $t2, $t1, $t0 # idx_tail
la $t4, input # location of character buffer
swap_characters:
lb $t5, input( $t1 ) # save front character in $t5
lb $t6, input( $t2 ) # save tail character in $t6
sb $t6, input( $t1 ) # store tail character as new front character
sb $t5, input( $t2 ) # store front character as new tail character
addi $t1, $t1, 1 # increment front index
addi $t2, $t2, -1 # decrement tail index
slt $t7, $t1, $t2 # if ( $t1 < $t2 ) $t7 = 1, zero otherwise
bnez $t7, swap_characters
# print the result:
li $v0, PRINT_STRING_SERVICE
la $t0, input
add $a0, $t0, $zero
syscall
exit_the_prog:
li $v0, SERVICE_EXIT
syscall
# procedures
# find the length of input string:
# $a0 contains the address of the string
# $ returns result in $t3
string_length:
addiu $sp, $sp, -20 # to preserve 5 4-byte regs
sw $ra, 0($sp)
sw $t1, 4($sp)
sw $a0, 8($sp)
sw $t2, 12($sp)
sw $t4, 16($sp)
move $t4, $a0 # $t4 = address of the string
move $t3, $zero # $t3 = index of character
li $t1, NEWLINE
compare_char_2_newline:
addu $a0, $t4, $t3 # addr of a char = address of the string + index of character
lb $t2, 0($a0) # load next char from input string
beq $t1, $t2, length_is_ready # compare char with \n
addi $t3, $t3, 1 # increment index
j compare_char_2_newline
length_is_ready:
lw $ra, 0($sp)
lw $t1, 4($sp)
lw $a0, 8($sp)
lw $t2, 12($sp)
lw $t4, 16($sp)
addiu $sp, $sp, 20
jr $ra # return back to the caller
# string_length ends