Формализация комментарии в ответ
J
/JR
можно эмулировать с JAL
/JALR
как последнего выполняет супер-набор операций первого.
Как указано в @Jester, подпрограммы (функции на языке жаргона C) должны быть осторожны, чтобы сохранить их обратный адрес, присутствующий в $ra
.
Если подпрограмма - это обычная листовая (то, что не делает никакого вызова) $ra
должен быть где-то сохранен.
На самом деле и JAL
/JALR
и J
/JR
могут быть реализованы один через другой:
Эмуляция JAL
/JALR
с J
/JR
Original Emulated
jal foo la $ra, ret_label
j foo
ret_label:
Эмуляция J
/JR
с JAL
/JALR
Original Emulated
j foo prolog:
addi $sp, $sp, -4
sw $ra, ($sp)
jal foo
epilog:
lw $ra, ($sp)
addi $sp, $sp, 4
Для этого код должен быть возвращен до epilog
. Предполагается, что $ra
в основном сохраняется в подпрограммах (отсюда и названия этикеток). Огромное спасибо @EOF за ошибку в этом фрагменте.
Как @Peter отмечалось, доступ к $pc
приводит к проще (для людей) эмуляции JAL
/JALR
.
Как @EOF отметил, некоторые RISC-машина на самом деле имеют только одну инструкцию для JAL
/JALR
и J
/JR
с учетом их врожденной запутанности.
Учитывая, что прыжки и звонки происходят очень часто в типичной программе, возможность легко выполнять (и выполнять их быстро) является обязательной для любой успешной ISA.
Они не являются абсолютно необходимыми, но вам нужно быть осторожными, чтобы сохранить '$ ra'. – Jester
Если вы можете эмулировать JAL, получив адрес в '$ ra' каким-либо другим способом, вам это не понадобится. Но я не знаю MIPS достаточно хорошо, чтобы узнать, есть ли способ PIC для этого. –
C имеет инструкцию 'goto', которая, похоже, работает как инструкция J. В операциях 'break' и' continue' также может быть сказано и об этом. –