Это функция; при записи $ra
содержит адрес возврата, на который ваш абонент хочет, чтобы вы перескочили назад.
Наряду с наличием первых 4 целочисленных аргументов в $ a0 .. $ a3, это является частью контракта между вызывающим и вызываемым абонентом. это необходимо для того, чтобы они согласились заставить вызовы функций работать. Эта часть соглашения о вызовах , конечно, разработана на основе инструкции MIPS jal
, поэтому вызов / возврат функции может быть выполнен с помощью одной инструкции каждая. Именно поэтому $31
имеет символ c name $ra
= обратный адрес.
Регистр не может содержать «ничто», это всегда 32-битное значение.
Если какой-то код установит $ra
в 0 или неверный адрес и перейдет к этой функции с помощью j
вместо jal
, он вернется к sh, когда вернется, и это будет ошибкой вызывающего. Ваша функция может просто предположить, что $ra
содержит действительный адрес возврата при входе в функцию, будь то рекурсивный вызов или какой-либо другой вызывающий объект.
(Это своего рода точка рекурсивных функций, которую вы действительно просто выполняем вызов функции для этой функции, и не имеет значения, откуда вы вызвали.)
Обратите внимание, что метка верхнего уровня в программе (например, в симуляторе MARS) равна не строго функция.
В MARS этот ярлык обычно называют main
, несмотря на тот факт, что $ra
содержит мусор или 0
в этой точке, поэтому он должен выйти с выход из системного вызова; jr $ra
приведет к sh.
(В C, main
- это истинная функция, которая обычно достигается из точки входа _start
, которая устанавливает вещи перед вызовом main. В C Сам по себе main
может быть рекурсивным без каких-либо специальных уловок. Если вы пишете программы для запуска под реальной ОС, а не игрушечной системой, которую эмулирует MARS, вы обычно используете метку _start:
для своей истинной точки входа из ядра, или вы просто напишите основную и ссылку с кодом запуска, предоставляемым библиотекой C, которая вызывает main
.)