CALL
принимает только относительный адрес (метку) и автоматически сохраняет текущий PC
(позже используемый для расчета обратного адреса) в %o7
. JMPL
, с другой стороны, принимает только абсолютный адрес в регистре и может хранить текущий PC
в произвольном регистре.
Соглашение о вызове функции в обоих случаях одинаково. CALL
более удобен для меток и JMPL
для указателей функций. Последний может использоваться для эмуляции первого путем загрузки адреса адреса в регистр первым.
Что касается возвращения, как RET
и RETL
синтетические инструкции, которые будут превращены в JMPL
ассемблере, используя правильный обратный регистр: RET
становится JMPL %i7+8,%g0
и RETL
становится JMPL %o7+8,%g0
. RET
предполагает, что вы создали новое окно регистрации (таким образом, исходный %o7
теперь %i7
), и вы должны следовать ему с инструкцией RESTORE
в слоте задержки.
Update: RETURN
инструкция по-видимому, был введен в Sparc v9, и сочетает в себе JMPL
(имеющий второй операнд %g0
) и RESTORE
(без операндов). Таким образом, его можно удобно использовать для завершения нелистовой функции, где вы обычно используете пару RET; RESTORE
.
Я не знаю, как все работает под SPARC или под вашим компилятором (что является вашим компилятором?), Но обычно язык 'assembly' не заботится и не определяет соглашение о вызове, которое определенная обычно определяется на других языках, таких как C или C++ (с точки зрения ABI). – user2485710
Я считаю, что язык ассемблера должен определять механизм вызова, посредством которого пользователь может вызвать функцию, а затем вернуться в место, где вызывается функция. – user3185252