user366312
user366312

Reputation: 16908

Converting a string into numbers

# replacing all digits in a string with their complement in 9.
.data
    string: .asciiz "123471863"

.text
main:
    # load string's 1st address into the memory
    la $a0, string

    # initialize the loop-counter
    li $t0, 0
    li $t1, 9 # complement envelope for later use

    # start the loop    
start_loop: 
    lb $t2, ($a0) # Take one character from string

    # loop termination condition
    beq $t2, $zero, end_loop # terminate if null-value found

    subi $t2, $t2, 48 # convert it to a digit
    sub $t2, $t1, $t2 # apply complement to $t2
    sw $t2,($a0) # restore the string-byte content

    addi $a0, $a0, 1 # go to next string-byte
    addi $t0, $t0, 1 # increment loop-counter

    j start_loop
end_loop: 

    # print string  
    la $a0, string # load 1st address of the string
    li $v0, 4 # syscall for string print   
    syscall

    move $a0, $t0 # load 1st address of the string
    li $v0, 1 # syscall for string print   
    syscall

    # exit program
    li $v0, 10
    syscall

The program isn't working as expected. After 1st iteration, the $a0 register isn't giving the correct value. Apparently, sw $t2,($a0) is destroying the original address.

How can I get over this issue?

Upvotes: 0

Views: 103

Answers (1)

Alain Merigot
Alain Merigot

Reputation: 11537

There is no problem to differentiate a null and a '0'. null is 0, while '\0' is 48.

Your test

    beq $t2, $zero, end_loop # terminate if null-value found

is perfectly correct and will detect the end of string.

What is incorrect is you algorithm.

A way to complement a number in C, would be :

while(c=*str){
  c=c-'0' ; // transform the number to integer
  c=9-c;    // complement it
  c += '0'; // add 48 to turn it back to a character
  str++;
}

You are missing the last conversion to character.

If you change

    sub $t2, $t1, $t2 # apply complement to $t2

to

    sub $t2, $t1, $t2 # apply complement to $t2
    addi $t2, $t2, 48

all should work.

Alternatively, ou can simplify your algorithm and remark that the computation c=9-(c-48)+48 is equivalent to c=105-c. Add before start_loop

   li $t4 105 ## 

and replace the three lines

    subi $t2, $t2, 48 # convert it to a digit
    sub $t2, $t1, $t2 # apply complement to $t2
    addi $t2, $t2, 48

by

   sub $t2,$t4,$t2  # complement to 9 directly on char representing the digit

Upvotes: 1

Related Questions