callпсевдо

call

псевдо
Асемблер RISC-V Посилання

lyszt.net охоплює call та інші інструкції RISC-V більш детально.

Опис

call запускає функцію та обробляє повернення. Він виконує перехід до функції та зберігає адресу повернення в ra, що дозволяє функції повернутися. Це псевдоінструкція, яка зазвичай розгортається в інструкцію нижче.

jal ra, label

Коли функція розташована надто далеко, щоб один перехід міг до неї дістатися, асемблер підставляє довшу послідовність, яка покриває цю відстань. Запис call з іменем функції виражає намір і залишає вибір форми асемблеру. Запис jal описує перехід і збереження адреси повернення. Рядок нижче викликає функцію square.

call square

Виклик функції також потребує узгодження того, як інформація передається між викликачем і викликаним. Це узгодження називається конвенцією викликів. Викликач поміщає вхідні дані функції в регістри аргументів, названі a0, a1 тощо, і читає результат з a0 після повернення функції. Обидві сторони дотримуються того самого правила, тому код, написаний окремо, усе одно працює разом.

Кожен call перезаписує ra. Функція, яка сама робить виклики, зберігає отриманий ra перед їх виконанням, а потім відновлює це значення перед власним поверненням. Без цього адреса повернення внутрішнього виклику замінює зовнішню, і функція не може повернутися. Функції, яка більше нічого не викликає, не потрібно зберігати ra.

Посібник RISC-V стверджує, що стандартна програмна конвенція викликів використовує x1 як регістр адреси повернення. jal досягає цілей у межах плюс-мінус 1 МіБ, де 1 МіБ — це 1 048 576 байтів. Дальша ціль потребує auipc, за яким іде jalr, що досягає будь-якого місця в 32-бітному діапазоні адрес відносно pc.

Приклад викликає square з 6 у a0 і після цього знаходить 36 у a0. Аргумент входить, а результат виходить через конвенцію.

Розгортається до

jal ra, label

Асемблер замінює цю псевдоінструкцію реальною інструкцією або інструкціями, переліченими вище.

Приклад

call square      # jumps to square; ra holds the return address