17.5. Стековые фреймы для вложенных подпрограмм
Для хранения адресов возврата цепочки вложенных подпрограмм лучше всего подходит стек. Очевидно, что при вызове каждой из этих подпрограмм в стеке процессора формируется полный стековый фрейм. В этой связи важно отметить, что сохраненное содержимое регистра FP в текущем фрейме на вершине стека — это указатель стекового фрейма той подпрограммы, которая вызвала текущую подпрограмму.
В программе, приведенной в таблице 17.4, главная подпрограмма вызывает подпрограмму SUB1, которая, в свою очередь, вызывает подпрограмму SUB2. Стековые фреймы этих двух вложенных подпрограмм изображены на рис. 17.6. Все их параметры передаются через стек. На рисунках показаны только поток выполнения подпрограмм и их данные — реализация основных задач опущена.
Таблица 17.4
Метка |
Команда |
Операнды |
Комментарий |
Главная программа (MAIN) |
|||
|
Move |
PARAM2,-(SP) |
Помещение параметров в стек |
|
Move |
PARAM1,-(SP) |
|
|
Call |
SUB1 |
Вызов подпрограммы |
|
Move |
(SP),RESULT |
Сохранение результата |
|
Add |
#8,SP |
Восстановление указателя стека |
|
……. |
|
|
Первая подпрограмма (SUB1) |
|||
SUB1 |
Move |
FP,-(SP) |
Сохранение указателя фрейма |
|
Move |
SP,FP |
Загрузка указателя фрейма |
|
MoveMultyple |
R0-R3,-(SP) |
Сохранение регистров |
|
Move |
8(FP),R0 |
Считывание первого параметра |
|
Move |
12(FP),R1 |
Считывание второго параметра |
|
……. |
|
|
|
Move |
PARAM3,-(SP) |
Помещение параметров в стек |
|
Call |
SUB2 |
Вызов подпрограммы |
|
Move |
(SP),+R2 |
Выталкивание результата работы SUB2 в R2 |
|
….. |
|
|
|
Move |
R3,8(FP) |
Помещение ответа в стек |
|
MoveMultyple |
(SP)+,R0-R3 |
Восстановление регистров |
|
Move |
(SP),+FP |
Восстановление указателя фрейма |
|
Return |
|
Возврат в главную программу |
Вторая подпрограмма (SUB2) |
|||
SUB2 |
Move |
FP,-(SP) |
Сохранение указателя фрейма |
|
Move |
SP,FP |
Загрузка указателя фрейма |
|
MoveMultyple |
R0-R1,-(SP) |
Сохранение регистров R0,R1 |
|
Move |
8(FP),R0 |
Считывание параметров |
|
……. |
|
|
|
Move |
R1,8(FP) |
Помещение в стек результата работы SUB2 |
|
MoveMultyple |
(SP)+,R0-R1 |
Восстановление регистров R0,R1 |
|
Move |
(SP),+FP |
Восстановление указателя фрейма |
|
Return |
|
Возврат управления подпрограмме SUB1 |
Рис. 17.6. Стековые фреймы программы, приведенной в табл. 4.
Порядок выполнения этой программы следующий. Главная программа помещает в стек два параметра, рагаm2 и paraml (именно в таком порядке), а затем вызывает подпрограмму SUB1. Данная подпрограмма должна вычислить некоторое значение и передать его обратно главной программе через стек. В ходе вычислений SUB1 вызывает вторую подпрограмму SUB2, выполняющую некоторую подзадачу. Подпрограмма SUB1 передает подпрограмме SUB2 один параметр рагаmЗ, и получает результат. После того как в подпрограмме SUB2 будет выполнена команда RETURN, подпрограмма SUB1 сохранит этот результат в регистре R2. Затем подпрограмма SUB1 продолжит свои вычисления, а закончив их, передаст ответ главной программе через стек. Когда управление будет возвращено главной программе, она сохранит полученный результат в памяти по адресу RESULT и продолжит свою работу со следующей команды. Этот процесс достаточно подробно описан в комментариях в таблице 17.4. Первым делом каждая подпрограмма устанавливает указатель фрейма (предварительно записав в стек его исходное содержимое) и сохраняет значения тех регистров, которыми она собирается оперировать. Например, подпрограмма SUB1 использует четыре регистра, от R0 до R3, a подпрограмма SUB2 — два регистра, R0 и R1. Все указанные регистры, а также указатель стека восстанавливаются перед выходом из подпрограммы.
Для загрузки параметров из стека и помещения результатов обратно в стек используется индексный режим адресации с использованием регистра указателя фрейма FP. В этих операциях, как и в случае стека, показанного на рис. 17.6, задается байтовое смещение 8,12 и т. д. Обратите внимание на тот факт, что за удаление параметров из стека всегда отвечает вызывающая программа. Эту операцию выполняет команда Add в главной программе и команда Move, расположенная по адресу 2164 в подпрограмме SUB1.
