Команда enter, обычно являющаяся первой командой процедуры, выделяет заданный
объем стекового пространства для локальных (автоматических) параметров процедуры,
предоставляя процедуре указатель на выделенную область (в качестве такого указателя
используется регистр ЕВР) и смещая указатель стека ESP так, чтобы он указывал
на начало свободного стекового пространства. В результате процедура имеет возможность
обращаться по ходу своего выполнения к своим локальным параметрам и, в то же
время, пользоваться оставшимся пространством стека для временного сохранения
в нем любых данных с помощью команд push и pop. Команда leave в конце процедуры
выполняет обратные действия, возвращая стек в исходное состояние и уничтожая
область локальных переменных. Локальными, как известно, называются как раз те
переменные, которые существуют только в течение времени выполнения некоторой
процедуры, и автоматически исчезают после се завершения.
Команды enter и leave используются многими языками высокого уровня для управления
доступом к локальным переменным вложенных процедур.
Команда enter имеет два операнда. Первый (16-битовое непосредственное значение)
определяет число байтов, выделяемых в стеке для локальных переменных. Для 32-разрядных
приложений место в стеке выделяется двойными словами (по 4 байт), для 16-разрядных
- словами (по 2 байт). Второй операнд (8-битовос непосредственное значение)
задаст так называемый лексический уровень процедуры, характеризующий степень
ее вложенности. В зависимости от значения лексического уровня, команда enter
выполняется по-разному. При лексическом уровне, равном 0, реализуется невложенная
форма команды enter. В этом случае после входа в процедуру (командой
call) с
сохранением в стеке адреса возврата, в стек заносится текущее содержимое регистра
ЕВР, в ЕВР копируется текущее значение указателя стека, а указатель стека смещается
на число байтов, заданное первым операндом команды enter
. Создаваемая
на сте-ке структура носит название стекового кадра, а регистр ЕВР выполняет
в данном случае функцию указателя стекового кадра.
Подпрограмма имеет возможность обращаться
к своим локальным переменным по адресам ESP-4 и ESP-8 (для случая резервирования
места под две переменные). Занеся в стек по этим адресам некоторые данные (полученные
в качестве параметров вызова через регистры общего назначения или созданные
самостоятельно) подпрограмма может затем многократно к ним обращаться, не боясь
их затирания в процессе использования стека. Поскольку команда enter настроила
указатель стека на область, находящуюся за пределами локальных переменных, программа
может использовать команды push для сохранения в стеке временных данных.
Команда leave, размещаемая в самом конце процедуры, перед завершающей командой
ret, копирует содержимое ЕВР в ESP, освобождая (в логическом плане) область
локальных переменных, и снимает со стека сохраненное там исходное содержимое
ЕВР. После этого командой ret можно вернуться в вызывающую процедуру.
Поскольку первый параметр команды enter имеет размерность слова, процедура в
принципе имеет возможность зарезервировать в стеке для своих локальных переменных
до 64 Кбайт стекового пространства.
Лексические уровни, отличные от 0, используются в тех случаях, когда по правилам
языка высокого уровня каждая вложенная процедура имеет право обращаться к локальным
переменным всех вышележащих процедур, но не к процедурам, находящимся на параллельных
с ней ветвях вложенности. Другими словами, область видимости переменных распространяется
на все вложенные процедуры, но две подпрограммы, вызываемые из одной и той же
(вышележащей) процедуры, "не видят" друг друга.
В таких случаях главной процедуре назначается лексический уровень 1, все вызываемые
из нее подпрограммы получают значение лексического уровня 2, подпрограммы, вызываемые
из этих процедур, имеют уровень 3 и т.д. Команды enter при ненулевом значения
второго параметра создают в стеке стековые кадры с более сложной структурой.
Отличие такого стекового кадра от рассмотренного выше заключается в том, что
в него, помимо области локальных переменных, входят также указатели стековых
кадров всех вышележащих процедур. В результате любая подпрограмма может с помощью
своего указателя (т.е. содержимого ESP) обратиться к собственных! переменным,
а используя хранящиеся в стеке указатели кадров вышележащих процедур, "дотянуться"
и до их локальных переменных. По-прежнему команды leave освобождают стек от
стековых кадров вместе со всеми находящимися в них данными.
Пример
;Вызывающая процедура
call subrl
;Подпрограмма subrl
subrl proc
enter2048,0 ;Место под локальные данные
. . . ;Работа с локальными данными
leave
ret