Почему JALR используется вместо JAL для возврата из подпрограмм - PullRequest
3 голосов
/ 25 января 2020

Я узнал, что и jal, и jalr могут использоваться для вызова функций, тогда как, наоборот, только jal может использоваться для возврата из функций, подобных этой:

sum3:

    add a0, a0, a1
    add a0, a0, a2
    jalr x0, 0(ra)

Однако , этот код использует jal вместо jalr для возврата из функции, и он работает хорошо:

    call sum3
ret_sum3:   
    # following instructions
    # ...
sum3:

    add a0, a0, a1
    add a0, a0, a2
    jal x0, ret_sum3

В связи с этим, почему говорят, что jalr - это инструкция для возврата из функция? Я тоже могу использовать jal. 1014 *

1 Ответ

4 голосов
/ 25 января 2020

Дело в том, что вы можете упустить тот факт, что, как правило, функция или подпрограмма должны вызываться из разных мест кода (т. Е. Множественные вызовы подпрограммы распространяются по всему коду), поэтому она должна быть в коде можно вернуться и в другие места.

Адрес, на который переходит инструкция jal, определяется содержимым регистра pc плюс 21-битное постоянное смещение, которое кодируется в инструкция. Следовательно, подпрограмма, которая использует jal для возврата, ограничена возвратом по тому же (фиксированному относительно pc) адресу.


Может ли jal все еще использоваться для возврата подпрограммы?

Если ваша подпрограмма вызывается только из одного места в коде, она все равно может использовать jal для возврата к вызывающей стороне - при условии, что адрес возврата соответствует позиции в памяти, расположенной примерно в ± 1MB далеко от jal инструкции, используемой для возврата. Просто подумайте о том, чтобы вызывать подпрограмму как jal x0, sum3 вместо call sum3, если вы хотите предотвратить засорение регистра ra.

...