Стековый фрейм
На примере программы, представленной в предыдущем разделе, разберемся, как используется пространство стека. Во время выполнения подпрограммы применяемую ею информацию содержат шесть верхних элементов стека. Эта область составляет собственное рабочее пространство подпрограммы, создаваемое при ее вызове и освобождаемое, когда управление возвращается вызывающей программе. Она называется стековым фреймом. Если для локальных переменных подпрограммы требуется дополнительное пространство, его также можно выделить в стеке.
Пример типичного расположения информации в стековом фрейме приведен на рис. 17.5.
Рис. 16.5. Пример стекового фрейма
В дополнение к указателю стека SP можно использовать еще один регистр, называемый указателем фрейма (Frame Pointer, FP). Он облегчает доступ к параметрам подпрограммы и ее локальным переменным. Эти локальные переменные используются только внутри подпрограммы, так что оперативную память для их хранения удобнее всего выделить прямо в стековом фрейме, связанном с данной подпрограммой. В нашем случае предполагается, что подпрограмма получает четыре параметра, применяет три локальные переменные и сохраняет содержимое регистров R0 и R1, которые она использует для своих нужд.
Поскольку регистр FP указывает на область оперативной памяти, расположенную непосредственно над сохраненным в стеке адресом возврата, с его помощью легко обращаться к параметрам и локальным переменным, применяя индексный режим адресации. Параметры адресуются так: 8(FP), 12(FP) и т. д., а локальные переменные так: -4(FP), -8(FP),.... Содержимое регистра FP в ходе выполнения подпрограммы остается неизменным, тогда как указатель стека SP должен всегда указывать на верхний элемент стека.
Теперь посмотрим, что происходит с указателями SP и FP при создании, использовании и уничтожении стекового фрейма в результате вызова конкретной подпрограммы. Будем считать, что перед вызовом подпрограммы SP указывает на старую вершину стека.
Вызывающая программа помещает в стек четыре параметра. Затем выполняется команда CALL, которая помещает в стек адрес возврата и передает управление подпрограмме. Теперь SP указывает на элемент стека, содержащий адрес возврата, и в следующий момент будет выполнена первая команда подпрограммы. Именно в это время указателю фрейма FP присваивается нужный адрес. Поскольку в качестве регистра FP обычно выступает один их регистров общего назначения, он может содержать информацию, нужную вызывающей программе. Поэтому его содержимое тоже сохраняется в стеке. А поскольку на вершину стека, которая будет началом стекового фрейма, указывает регистр SP, содержимое данного регистра копируется в регистр FP.
Итак, первые две команды подпрограммы должны быть такими:
Move FP,-SP
Move SP,FP
После их выполнения регистры SP и FP указывают на сохраненное содержимое регистра FP. Далее в стеке выделяется пространство для трех локальных переменных, для чего выполняется команда
Subtract #12,SP
Напоследок в стеке сохраняется содержимое регистров R0 и R1. Теперь стековый фрейм сформирован и имеет такую структуру, как на рис. 16.5.
Далее подпрограмма, выполнив свою непосредственную задачу, выталкивает ранее сохраненные значения регистров R0 и R1 обратно в эти же регистры, удаляет из стекового фрейма локальные переменные с помощью команды
Add #12,SP
и выталкивает старое значение регистра FP обратно в этот регистр. Теперь регистр SP указывает на адрес возврата и можно выполнить команду RETURN, возвращающую управление вызывающей программе.
За удаление параметров из стекового фрейма отвечает вызывающая программа. Некоторые из таких параметров могут содержать возвращенные подпрограммой результаты вычислений. После того как это будет сделано, указатель стека должен указывать на исходную вершину стека.
Дата добавления: 2015-09-29; просмотров: 2549;