MIPS - JAL путаница: $ra = ПК + 4 или ПК + 8?

Мне сложно понять, как работает команда jal в процессоре MIPS. Мои два вопроса:
a) Какое значение хранится в R31 после "jal": ПК + 4 или ПК + 8?
b) Если это действительно ПК + 8, что происходит с инструкцией на ПК + 4? Выполняется ли оно перед прыжком или никогда не выполняется?

В Паттерсоне и Хеннесси (четвертое издание), стр. 113:

"команда перехода и перехода: инструкция, которая перескакивает и адресует и одновременно сохраняет адрес следующей инструкции в регистре ( $ra в MIPS)"

"(ПК): регистр, содержащий адрес инструкции в исполняемой программе"

После прочтения этих двух утверждений следует, что значение, сохраненное в $ra, должно быть (ПК + 4).

Однако в справочных данных MIPS (зеленая карта), которые поставляются вместе с книгой, алгоритм команды jal определяется следующим образом: "Переход и ссылка: jal: J: R [31] = ПК + 8; ПК = JumpAddr"

Этот веб-сайт также гласит, что "это действительно ПК + 8" , но, как ни странно, после этого он говорит, что, поскольку конвейерная обработка является продвинутой тема "мы будем считать обратный адрес ПК + 4" .
Я пришел из сборки 8086, поэтому я знаю, что существует большая разница между возвратом к адресу и следующему за ним, потому что программы не будут работать, если я просто предполагаю, что это не так. Спасибо.

Ответ 1

Адрес в $ra - это действительно PC + 8. Инструкция сразу после команды jal находится в интервале задержки ветвления". Он выполняется до ввода функции, поэтому ее нельзя повторять при возврате функции.

Другие команды ветвления на Mips также имеют временные интервалы задержки.

Слот задержки используется, чтобы сделать что-то полезное за время, необходимое для выполнения команды jal.

Ответ 2

У меня тот же вопрос. Я нашел этот отличный ответ Ричарда, а также еще одну ссылку, которую я хочу добавить здесь.

Ссылка http://chortle.ccsu.edu/AssemblyTutorial/Chapter-26/ass26_4.html с этим замечательным объяснением двойного добавления 4 на ПК. Таким образом, фактическое исполнение имеет два дополнения: 1) newPC = PC + 4 путем конвейерной обработки и 2) другое дополнение $ra = newPC + 4 командой jal, приводящее к результату $ra = (адрес команды jal) +8.