В данном материале рассмотрена работа со стеком на примере вычисления факториала.
Работа со стеком, в рассматриваемом примере, аналогична алгоритму работы со стеком компилятором Clang из состава среды CM_LYNX.
.SECTION /DOUBLE64 /CHAR32 .program;
.SECTION /DOUBLE64 /CHAR32 .program._fact;
.ALIGN_CODE 4;
.GLOBAL _fact;
.TYPE _fact,@function;
_fact:
J27 = J27 - 8 (NF);; // Нарастить стек
K26 = J27;;
COMP(J27, J26);; // Проверка переполнения стека
IF JLT, CALL.L __STACK_OVERFLOW (NP) (ABS);;
[J27 + 15] = CJMP;; // Положить адрес возврата на стек
COMP(J4, 1);;
IF NJLE, JUMP LBB0_2; NOP;; // i < 1
J8 = 1;; // Если i < 1 - вернуть 1
JUMP LBB0_3; NOP; NOP;;
LBB0_2:
[J27 + 11] = J4;; // Положить на стек i
J4 = J4 - 1 (NF);; // Параметр функции - i-1
CALL.L _fact;; // Вызывать функцию fact
XR0 = J8;; // Результат функции - fact(i-1)
XR1 = [J27 + 11];; // Считать i со стека
XR0 = R1 * R0 (U) (I) (NF);; // Умножение
J8 = XR0;; // Вернуть i*fact(i-1)
LBB0_3:
CJMP = [J27 + 15];; // Взять адрес возврата со стека
J27 = J27 + 8 (NF);;
K26 = J27;;
CJMP (ABS);; // Выход
_fact.end:
.SECTION /DOUBLE64 /CHAR32 .program._main;
.ALIGN_CODE 4;
.GLOBAL _main;
.TYPE _main,@function;
_main:
J27 = J27 - 4 (NF);; // Нарастить стек
K26 = J27;;
COMP(J27, J26);; // Проверка переполнения стека
IF JLT, CALL.L __STACK_OVERFLOW (NP) (ABS);;
[J27 + 11] = CJMP;; // Положить адрес возврата на стек
J4 = 12;; // i - аргумент функции
CALL.L _fact;; // Вычислить fact(i)
[J27 + 9] = J8;; // Получить результат, должно быть 479001600 для 12!
J8 = 0;; // Код возврата из main
CJMP = [J27 + 11];; // Взять адрес возврата со стека
J27 = J27 + 4 (NF);; // Уменьшить стек
K26 = J27;;
CJMP (ABS);; // Выход
_main.end: