Я думаю, что основная проблема в том, что вопрос 6 просит вас работать с числами от 1 до 100, тогда как ваш код работает с 1 до 999!
Вызов подпрограммы выглядит нормально,Некоторые предложения:
1) У вас странная смесь основных операций против псевдо-операций.Инструкции ori
вверху могут быть написаны с использованием li
(так же, как и константы для системных вызовов внизу).В качестве альтернативы, если вы намеренно хотите использовать базовые операции в качестве учебного упражнения, обратите внимание, что move $a0, $t1
можно записать как addu $a0, $t1, $0
(или or $a0, $1, $0
также работает).
2) Условная ветвь с sltu
и beq
можно записать как bge $t1, $t4, diff
.Это псевдооператор, который расширяется до sltu
и beq
, но интересен тем, что автоматически использует $1
в качестве временного регистра - по договоренности этот регистр зарезервирован для использования в качестве «временного ассемблера» и называется $at
.
3) sll $0, $0, $0
- это действительно sllv
инструкция, так как в качестве величины сдвига есть регистр.Канонический MIPS no-op - это sll $0, $0, 0
, который собирается с кодом операции 0x00000000
.Более того, просто напишите nop
.
4) Там, где используются явные интервалы задержки ветвления (обратите внимание, что некоторые ассемблеры автоматически переупорядочивают инструкции для их заполнения - например, gas
делает это, если вы не скажете, чтобы это нес .set reorder
), полезно четко обозначить их, чтобы они выделялись.Полезное соглашение заключается в том, чтобы дать им дополнительный отступ:
move $a0, $t1 # put n in $a0
jal square # jump to square and save position to $ra
nop # no-op
(A nop
имеет тенденцию выделяться в любом случае, но если вы начнете пытаться заполнить их полезными инструкциями, вы быстро сойдете с умаесли вы не пометите их каким-то образом.)