Я работаю над заданием в 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
Есть ли способ двигаться вперед по строке, не удаляя ее элементы и не получая измененную строку в качестве вывода? Любая помощь будет оценена спасибо!
Ваш код явно не делает то, что должен, потому что тогда вы бы не задавали здесь вопрос.
Что делает ваш код в основном
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, которые предполагают отсутствие слотов задержки ветвления. Я предполагаю, что многие студенты не знают об этой концепции, если они только изучают основы ассемблера, и их профессор не обременял их этим усложнением, пока они не начали говорить об архитектуре компьютера и о том, как работают конвейерные процессоры.