0
votes

I'm working on an assignment in MIPS. I want to print the stored string without the decimal point i.e the output should be 11011 for 110.11 .

I think my code is doing what it's supposed to, but it's not showing any output. I debugged it and it turns out that the addi statement just keeps removing the first element of the string so there's nothing left in the end.

.data
        string: .asciiz "110.11"
.text
.globl main
.ent main
main:
     la $t1,string
     li $t5,46              #ascii code of .=46

     LOOP:
     lb $t0,($t1)
     beq $t0,$t5,SKIP       #skip point if found
     beq $t0, $zero, exit 
     sb $t0,($t1)
     addi $t1, $t1, 1       #i++

     j LOOP

     SKIP:
     addi $t1, $t1, 1
     j LOOP

     exit:  
     li $v0,4
     move $a0,$t1
     syscall

     li $v0,10
     syscall
     jr $ra
.end main

Is there any way to move forward through the string without deleting its elements and getting modified string as output? Any help would be appreciated thankyou!

1

1 Answers

1
votes

Your code is obviously not doing what it's supposed to, because then you wouldn't ask the question here.

What your code basically does is

while (*string) {
  if (*string != '.')
    *string = *string;
  string++;
}
syscall (string);

So you are not only not removing the dot, but you print the empty string, or to be more precise, the terminating zero byte at the and of the string.

You say "it turns out that the addi statement just keeps removing the first element of the string so there's nothing left in the end". There seems to be a lack of understanding what that statement does and how it relates to zero terminated strings. The addi in this loop will advance the pointer till the end of the string, because that it what this loop does. Incrementing the pointer means that the pointer now points to the second byte, so you get the string starting at the next byte. The memory itself is not modified.

You can try something like this. It assumes that you configured your assembler to execute the statements in the order written, in other words reorder the statements so that the add of t1 will go into the slot after the branch.

main:
     la $t1,string
     move $t2,$t1
     move $t3,$t1           # t1 = t2 = t3 = string
     li $t5,46              #ascii code of .=46

LOOP:
     lb $t0,($t1)
     addi $t1, $t1, 1       #t1++
     beq $t0,$t5,SKIP       #skip point if found
     sb $t0,($t2)
     addi $t2, $t2, 1       #t2++
SKIP:
     bneq $t0, $zero, LOOP   # exit on end of string

     li $v0,4
     move $a0,$t3
     syscall

     li $v0,10
     syscall
     jr $ra

In C, this would be

t1 = t2 = t3 = string;
do {
  t0 = *t1++;
  if (t0 != '.')
    *t2++ = t0;
} while (t0 != 0);
syscall (t3);