При немедленной печати результата арифметической операции в мипах лучше хранить его непосредственно в $ a0? - PullRequest
0 голосов
/ 27 декабря 2018

Если вы собираетесь немедленно напечатать результат арифметических операций, почему вы все еще сохраняете результат в другом регистре и копируете его в $a0 вместо непосредственного использования $a0 при выполнении операций?Это лучшая практика?Или это что-то произвольное?

Обычный процесс, который я вижу у других, таков:

addi $t0, $zero, 50

li $v0, 1  
add $a0, $zero, $t0  
syscall

Потенциально ли это вызовет проблемы, если я сделаю это таким образом?

addi $a0, $zero, 50

li $v0, 1  
syscall

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

Единственное, что имеет значение, это содержимое регистра $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 просто даст людям больше читать, чтобы увидеть, что это просто создание константы или копированиерегистр.)

0 голосов
/ 27 декабря 2018

Это зависит.

Если syscall изменяет значение $a0 и вам все еще нужно это значение после системного вызова, то вам нужно каким-то образом его сохранить.

Однако симуляция syscall в SPIM и MARS не приведет к изменению каких-либо регистров, кроме тех, которые явно указаны в документации.Итак, если вы запускаете свой код, вам, как правило, не нужно беспокоиться о сохранении значения $a0.

Другая возможность состоит в том, что у человека, написавшего этот код, был какой-то другой кодэто будет выполнено позже - и этот код предполагает, что значение находится в $t0.

Или может быть, что дополнительная инструкция совершенно бессмысленна.Без контекста это невозможно сказать.


Кстати, li $t0, 50 и move $a0, $t0 гораздо более читабельны, чем addi $t0, $zero, 50 и add $a0, $zero, $t0.

...