Единственное, что имеет значение, это содержимое регистра $v0
и (для этого системного вызова) $a0
, когда выполняется syscall
.
Да, это очень часто встречаетсяувидеть неэффективный код от начинающих.Может быть, они скопировали + модифицированные примеры, не понимая или не следуя логике, что меньше кода / более простой код почти всегда лучше.(Часто более эффективный и обычно более простой для читателей-людей. Включая программиста, когда вы пишете / отлаживаете его. Меньше изменений архитектурного состояния при пошаговом отладке и т. Д.)
На MARS/ SPIM, системный вызов ABI не изменяет $a0
, поэтому данные все равно будут доступны в регистре после.Системный вызов Linux ABI имеет разные системные вызовы с разными номерами, но также сохраняет (почти?) Все регистры, кроме возвращаемого значения.
Копирование регистра перед системным вызовом может иметь смысл, если вы хотите, чтобы он был в другом регистре.чем $a0
для чего-то после системного вызова, например, чтобы сохранить его в регистре, пока вы передаете разные аргументы другому системному вызову, но в остальном это просто глупое раздувание кода.(Копирование после тоже подойдет.)
Почему вы используете li
для настройки $v0 = 1
, но вручную расширяете его до addi
для настройки $a0 = 50
?
Это не сделает машинный код более эффективным (ori
или addiu
не быстрее, чем addi
на любых реальных MIPS, AFAIK, хотя они могут быть на симуляторе / эмуляторе, где проверка переполненияв addi
принимает дополнительный код в эмуляторе.)
Но это сделает исходник asm более легким для чтения и более понятным.(Если вы понимаете, как ассемблеры обрабатывают псевдоинструкции li
и move
, выписывание addiu
или addu
вручную с помощью $zero
просто даст людям больше читать, чтобы увидеть, что это просто создание константы или копированиерегистр.)