Как изменить и распечатать строку в MIPS? - PullRequest
0 голосов
/ 13 июня 2019

Я работаю над заданием в MIPS.Я хочу напечатать сохраненную строку без десятичной точки, т.е. вывод должен быть 11011 для 110.11.

Я думаю, что мой код делает то, что должен, но не показывает никакого вывода.Я отладил его, и оказалось, что оператор addi просто удаляет первый элемент строки, поэтому в конце ничего не остается.

.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

Есть ли способ продвинуться вперед по строке, не удаляя ееэлементы и получение модифицированной строки в качестве вывода?Буду признателен за любую помощь!

1 Ответ

1 голос
/ 13 июня 2019

Ваш код явно не выполняет то, что должен, потому что тогда вы бы не задали вопрос здесь.

Что в основном делает ваш код

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

Таким образом, вы не только не удаляете точку, но и печатаете пустую строку, или, если быть более точным, завершающий нулевой байт в и из строки.

Вы говорите: «получается, что оператор addi просто удаляет первый элемент строки, поэтому в конце ничего не остается». Кажется, не хватает понимания, что делает это утверждение и как оно относится к строкам с нулевым символом в конце. addi в этом цикле будет продвигать указатель до конца строки, потому что это то, что делает этот цикл. Увеличение указателя означает, что указатель теперь указывает на второй байт, поэтому вы получаете строку, начинающуюся со следующего байта. Сама память не модифицируется.

Вы можете попробовать что-то вроде этого. Предполагается, что вы сконфигурировали ваш ассемблер для выполнения операторов в написанном порядке, другими словами, измените порядок операторов так, чтобы добавление t1 входило в слот после ветви.

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

В C это будет

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