Доступ к одному символу в строке

#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 инструкции, поэтому нет необходимости вручную сбрасывать регистр перед a LI .