Что не так с этим кодом MIPS/QtSPIM While Loop

Программы работают с ожидаемым результатом, но с ошибками ниже

Код

.data

.text
.globl main
main: 
  addi $t0, $t0, 0    # i = 0
  addi $t2, $0, 10    # n = 10
  j WhileCond         # goto WhileCond

  WhileLoop:
    li $v0, 1         # print_int
    move $a0, $t0     # $a0 = i (print i)
    addi $t0, $t0, 1
    syscall

  WhileCond:
    blt $t0, $t2, WhileLoop # if i < 10 goto WhileLoop

  j $ra

Сегмент пользовательского текста

[00400000] 21080000  addi $8, $8, 0           ; 10: addi $t0, $t0, 0 # i = 0 
[00400004] 200a000a  addi $10, $0, 10         ; 11: addi $t2, $0, 10 # n = 10 
[00400008] 08100007  j 0x0040001c [WhileCond] ; 12: j WhileCond # goto WhileCond 
[0040000c] 34020001  ori $2, $0, 1            ; 15: li $v0, 1 # print_int 
[00400010] 00082021  addu $4, $0, $8          ; 16: move $a0, $t0 # $a0 = i (print i) 
[00400014] 21080001  addi $8, $8, 1           ; 17: addi $t0, $t0, 1 
[00400018] 0000000c  syscall                  ; 18: syscall 
[0040001c] 010a082a  slt $1, $8, $10          ; 21: blt $t0, $t2, WhileLoop # if i 
[00400020] 1420fffb  bne $1, $0, -20 [WhileLoop-0x00400020] 
[00400024] 03e00008  jr $31                   ; 23: j $ra 

Ошибка

Exception occurred at PC=0x00000000
  Bad address in text read: 0x00000000
Instruction references undefined symbol at 0x800001dc
  [0x800001dc] 0x143a0000  bne $1, $26, 0 [ok_pc-0x800001d8]

person Jiew Meng    schedule 19.10.2011    source источник
comment
Это даже не собирается. j $ra не является допустимой инструкцией MIPS. Вы имеете в виду jr $ra.   -  person m0skit0    schedule 19.10.2011
comment
С jr $ra он отлично работает на симуляторе MARS (за исключением того, что $ra не имеет назначенного значения и вылетает при переходе к $ra). По какой причине я предполагаю, что вы получаете эту ошибку: Исключение произошло на ПК = 0x00000000 Неверный адрес в прочитанном тексте: 0x00000000   -  person m0skit0    schedule 19.10.2011
comment
Нужна ли эта строка на самом деле? Вернуться из основного метода?   -  person Jiew Meng    schedule 20.10.2011
comment
У вас нет вызова функции, поэтому в вашем случае эта строка не требуется. Если вы хотите использовать этот код как функцию, тогда потребуется эта строка, а также несколько других, таких как протокол входа/выхода функции (дополнительная информация о MIPS ABI). Также я бы не использовал j WhileCond, а скорее b WhileCond. Переходы обычно используются для дальних адресов, переходы — для ближних. Ветки AFAIK выполняются быстрее.   -  person m0skit0    schedule 20.10.2011
comment
@ m0skit0, я не думаю, что есть команда b. Я думаю, что beq $0, $0, WhileCond будет работать, хотя   -  person Jiew Meng    schedule 20.10.2011
comment
Есть b инструкция, по крайней мере, для MIPS IV. Проверьте документацию по MIPS.   -  person m0skit0    schedule 20.10.2011
comment
Инструкция b является сокращением на ассемблере для beq $0,$0,offset. MIPS имеет множество сокращений ассемблера.   -  person markgz    schedule 20.10.2011


Ответы (1)


addi $t0, $t0, 0    # i = 0

Не будет устанавливать $t0 в 0, а скорее оставит его без изменений. (move $t0, $zero) или (addi $t0, $0, 0) оба будут работать.

Также вы уверены, что $t0 и $t2 сохранены в системном вызове?

Наконец, ошибка, которую вы опубликовали, не появляется в вашем коде. У вас есть трассировка стека/дамп регистров или что-то еще, что может помочь в его отслеживании?

person user786653    schedule 19.10.2011
comment
Теперь он работает (похоже, что j $ra вызывает проблемы ... хотя я думаю, что @ m0skit0 прав, он вообще не должен работать ...). Я помню, что системный вызов мог не сохранять некоторые переменные... но пока это работало... как я могу решить эту потенциальную проблему? - person Jiew Meng; 19.10.2011
comment
Сохраняя его в стеке, все это объясняется здесь. И очень вероятно, что @m0skit0 понял это правильно, я не помню начальных условий SPIM. - person user786653; 19.10.2011