#string #assembly #mips #spim #mars-simulator
#строка #сборка #mips #spim #mars-симулятор
Вопрос:
Я использую что-то вроде SPIMS или MARS с функциями системного вызова.
Я читаю в строке (и это работает, потому что я могу ее распечатать) следующим образом:
li $v0, 8
la $a0, string
li $a1, 256
syscall
Однако у меня возникла проблема с доступом к одному символу строки. Поэтому, если я хочу получить доступ к первому символу и распечатать его, я пытаюсь это:
la $t0, string
lb $a0, ($t0)
li $v0, 4
sys call
Если я попробую что-то вроде этого:
la $a0, string
li $v0, 4
syscall
При этом выводится вся строка, поскольку строка указывает на всю строку.
Если я попробую что-то вроде:
la $a0, string
lb $a0, ($t0)
li $v0, 4
syscall
Это выдает ошибку out of bound. Я не понимаю, почему, хотя — разве символ не имеет длину в байт, и это просто загружает первый байт из строки в $ a0?
Спасибо
Ответ №1:
Просматривая документацию для функций системного вызова MARS, вы можете увидеть, что используемая вами служба 4 ожидает $a0
, что она будет «[адресом] строки с нулевым завершением для печати», что объясняет поведение, которое вы видите.
Вам нужна функция 11 «печать символа», которая печатает младший байт как символ. Другими словами, должно работать следующее (не проверено):
la $t0, string
lb $a0, ($t0)
li $v0, 11
syscall
Комментарии:
1. IMO вы всегда должны сбрасывать значения регистров перед выполнением LI. Вы никогда не знаете, что может быть в верхней половине слова.
2.
LI
это псевдо-операция, которую ассемблер обычно расширяет, заORI $rd,$zero, low16bits
которой следуетLUI $rd, hi16bits
. Полные 32 бита целевого регистра правильно установлены послеLI
инструкции, поэтому нет необходимости вручную сбрасывать регистр перед aLI
.