Строка MIPS (пустой режим) не печатается

Недавно, когда я начал изучать MIPS в университете, я столкнулся с проблемой при попытке напечатать одну строку, принять ввод пользователя, а затем распечатать другую строку и принять ввод пользователя. Оба пользовательских ввода должны быть сохранены в регистрах a0 и a1 соответственно.

Имена каждой строки: promptD для ввода Dividend и enterD для ввода Divisor (вы можете догадаться, что это программа-калькулятор беззнакового деления).

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

Я думаю, что я неправильно смещаю свой первый регистр .data, чтобы достичь моего второго регистра .data. Проблема, которую я заметил, когда пробовал QTspim, xspim, PCspim и MARS, заключается в том, что все 4 из них дают первой строке в .data другой начальный адрес регистра.

Например: строка «Enter Dividend» будет находиться по адресу регистрации 0x10010000 в MARS, но будет начинаться с 0x10000000 в PCspim. Следующий адрес регистра для «Enter Divisor» будет либо 0x10010011 в MARS, либо 0x10000010 в PCspim.

В текущем состоянии через MARS приведенный ниже фрагмент программы просит пользователя ввести дивиденд, и значение будет сохранено. Сразу после сохранения в a0 код завершится ошибкой из-за исключения времени выполнения строки 37 (которое является всего лишь третьим системным вызовом) по адресу 0x00400024: адрес вне диапазона 0x00000004. Он вообще не предлагает "Enter Divisor".

Чтобы действительно увидеть проблему в действии, я думаю, что запуск этого в MARS поможет прояснить ситуацию. Это вопрос компенсации? Я забиваю реестр, не видя его? Я не нашел здесь большой справки по MIPS, которая решала бы проблемы без псевдо-инструкций. Я понимаю, что с их помощью я мог бы загрузить адрес напрямую (la) ... но я не могу использовать их здесь.

Спасибо

    .globl main

    .data        #for the data

    promptD: .asciiz "Enter Dividend \n"
    enterD:  .asciiz "Enter Divisor \n"
  #  result: .asciiz "Result = "

    .text           #for the instructions

    main:

    #for Dividend
    addi $v0, $0, 4     #store string instr to v0

    lui $a0, 0x1001     #address of promptD

    syscall              #display promptD

    addi $v0, $0, 5     #store input instr to v0

    syscall             # Get dividend

    add $a0, $0, $v0        # Dividend to $a0


    #for Divisor
    addi $v0, $0, 4         #store string instr to v0

    lui $a1, 0x1001         #Where I think the problem is...
                            #Address of first string followed by add offset?
    addi $a1, $a1, 33       #Maybe incorrect offset?

    syscall                 #display enterD

    addi $v0, $0, 5         #store input instr to v0

    syscall                # Get divisor

    add $a1, $0, $v0        # Divisor to $a1

    #end snippet

person D Evans    schedule 08.10.2015    source источник


Ответы (1)


Вот проблемный код:

lui $a1, 0x1001         #Where I think the problem is...
                        #Address of first string followed by add offset?
addi $a1, $a1, 33       #Maybe incorrect offset?
  1. Вы используете неправильный регистр. Аргумент для системного вызова 4 должен быть помещен в $a0, а не в $a1.
  2. Смещение 33 неверно. Если вы посмотрите на средство просмотра сегментов данных на Марсе, вы увидите, что байт-ограничитель NUL для promptD расположен по адресу 0x10010010, а строка enterD начинается с 0x10010011 (если вам трудно читать шестнадцатеричные коды ASCII, вы можете отметить галочкой " ASCII "в средстве просмотра сегмента данных для просмотра данных в виде символов). Таким образом, смещение, которое вы должны использовать, - 0x11 (17 десятичных знаков).
person Michael    schedule 08.10.2015
comment
Привет, Майкл. Спасибо за помощь! Я знал, что изначально для адреса нужно было смещение 17 ... У меня был ТА, который сказал мне 33! Не знаю, откуда они это взяли. Что касается этих изменений, я их реализовал, но все еще не могу получить правильную строку для вывода. Я продолжаю дважды выводить Enter Dividend. - person D Evans; 08.10.2015
comment
У меня отлично работает. Ну, за исключением того, что вы неправильно завершаете программу с помощью системного вызова 10. - person Michael; 08.10.2015
comment
Еще раз спасибо! Я смог понять, почему он не печатает должным образом: я не изменил все регистры с a1 на a0, которые нужно было изменить. Я также добавил еще один оператор добавления внизу, чтобы вернуть ввод Dividend в a0. Я сделал первый оператор сложения, поместив значение Dividend в t0, чтобы можно было снова использовать a0. - person D Evans; 09.10.2015