Как изменить и напечатать строку в MIPS?

Я работаю над заданием в 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

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

В чем разница между методом "==" и equals()
В чем разница между методом "==" и equals()
Это один из наиболее часто задаваемых вопросов новичкам на собеседовании. Давайте обсудим его на примере.
Замена символа по определенному индексу в JavaScript
Замена символа по определенному индексу в JavaScript
В JavaScript существует несколько способов заменить символ в строке по определенному индексу.
0
0
1 670
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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);

Хороший хорошо объясненный ответ; хорошая работа, устраняющая недопонимание того, что значит перебирать байты строки. BTW, MARS и SPIM имитируют MIPS без слотов задержки перехода (для этого есть опция меню); вот почему вы обычно видите вопросы MIPS на SO, которые предполагают отсутствие слотов задержки ветвления. Я предполагаю, что многие студенты не знают об этой концепции, если они только изучают основы ассемблера, и их профессор не обременял их этим усложнением, пока они не начали говорить об архитектуре компьютера и о том, как работают конвейерные процессоры.

Peter Cordes 13.06.2019 19:24

Большое спасибо за разъяснение моего недоразумения. Теперь код работает отлично!

Miza 13.06.2019 22:03

Другие вопросы по теме