logo search
Языки программирования

7.8. Реализация на процессоре Intel 8086

Чтобы дать более конкретное представление о реализации идей стековой архитектуры, рассмотрим вход в процедуру и выход из нее на уровне машинных команд для процессора серии Intel 8086. В качестве примера возьмем:

procedure Main is

Global: Integer;

procedure Proc(Parm: in Integer) is

Local'1, Local2: Integer;

begin

Ada

Local2 := Global + Farm + Local 1 ;

end Proc;

begin

Proc(15);

end Main;

Процессор 8086 имеет встроенные команды push и pop, в которых подразуме­вается, что стек растет от старших адресов к младшим. Для стековых операций выделены два регистра: регистр sp, который указывает на «верхний» элемент в стеке, и регистр bр, который является указателем дна и идентифицирует ме­стоположение начала записи активации.

При вызове процедуры в стек помещается параметр и выполняется коман­да вызова (call):

mov ax, #15 Загрузить значение параметра

push ax Сохранить параметр в стеке

call Proc Вызвать процедуру

На рисунке 7.11 показан стек после выполнения этих команд — параметр и адрес возврата помещены в стек.

Следующие команды являются частью кода процедуры и выполняются при входе в процедуру; они сохраняют старый указатель дна (динамическая связь), устанавливают новый указатель дна и выделяют память для локальных переменных, уменьшая указатель стека:

push bp Сохранить старый динамический указатель

mov bp, sp Установить новый динамический указатель

sub sp,#4 Выделить место для локальных переменных

Получившийся в результате стек показан на рис. 7.12.

Теперь можно выполнить тело процедуры:

mov ax,ds:[38] Загрузить переменную Global

add ax,[bp+06] Прибавить параметр Parm

add ax,[bp-02] Прибавить переменную Local 1

mov ax,[bp] Сохранить в переменной Local2

Обращение к глобальным переменным делается через смещения относи­тельно специальной области памяти, на которою указывает регистр ds (сегмент данных). К параметру Parm, который располагается в стеке «ни­же» начала записи активации, обращаются при положительном смещении относительно bp. К локальным переменным, которые в стеке располагают­ся «выше», обращаются при отрицательном смещении относительно bp. Важно обратить внимание, что поскольку процессор 8086 имеет регистры и способы адресации, разработанные для обычных вычислений с исполь­зованием стека, то ко всем этим переменным можно обращаться одной ко­мандой.

При выходе из процедуры должны быть ликвидированы все изменения, сделанные при входе в процедуру:

mov sp,bp Очистить все локальные переменные

pop bp Восстановить старый динамический указатель

ret 2 Вернуться и освободить память параметров

Указатель вершины стека принимает значение указателя дна и таким образом действительно освобождает память, выделенную для локальных переменных. Затем старый динамический указатель выталкивается (pop) из стека, и bр те­перь указывает на предыдущую запись активации. Остается только выйти из процедуры, используя адрес возврата, и освободить память, выделенную для параметров. Команда ret выполняет обе эти задачи; операнд команды указы­вает, сколько байтов памяти, выделенных для параметра, необходимо вытол­кнуть из стека.

Подведем итог: как для входа, так и для выхода из процедуры требуется только по три коротких команды, и доступ к локальным и глобальным пере­менным и к параметрам является эффективным.