На главную
Подписка
Новости










Главная / MS-DOS / MS-DOS. РУКОВОДСТВО РАЗРАБОТЧИКА / Глава 2 / Локальная память в стеке Сделать домашней страницей Добавить в избранное Написать писмо

НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Локальная память в стеке

Для локальной памяти в стеке может быть зарезервирован блок стека посредством уменьшения указателя стека. Любые прерывания или вызовы, происходящие после этого, могут теперь обеспечить в этом блоке стека сохранение любых локальных данных, относящихся к прерванной программе. Это самый удобный способ сохранения данных, но требующий, чтобы доступ ко всем локальным переменным выполнялся через регистр BP (для обсуждения этого смотри предшествующий раздел, озаглавленный "Передача данных в стек"). Пример этого способа, снабженный примечаниями, содержится в листинге 2-8.



               Листинг 2-8. Использование стека для локальной памяти
         -----------------------------------------------------------------

                           ; Вызывающая процедура

                 ...    ...
                push    ; передача 3-го аргумента
                push    ; передача 2-го аргумента
                push   

Т.к. структура Stackframe определяется в текущем сегменте, нет необходимости перекрывать сегмент. Если используется смещение из другого сегмента, как например, при попытке использования шаблона из другого сегмента данных, то в ссылке необходимо использовать конструкцию SS: override (заместить). Отказ от выполнения этого требования приводит к выдаче сообщения об ошибке в макроассемблере MASM "Can't reach with segment reg" (невозможно найти регистр сегмента). Если когда-либо появится это сообщение, то оно означает, что для определения сегмента, к которому осуществляется доступ, текущий сегмент не принят во внимание и нужно решать эту проблему.


Если в стеке распределяется локальная память, то перед возвратом управления из программы она должна быть освобождена. Это можно выполнить путем добавления размера локальной памяти к стеку (возвращение к прежнему состоянию sub sp,offset bp или восстановление регистра BP из сохраненного значения (mov sp,bp)). Память можно не освобождать с помощью инструкции RET N, т.к. текущая вершина стека не содержит адрес возврата!


В большинстве компиляторов с языков высокого уровня предпочтительным способом хранения локальных данных является использование этой "временной" памяти в стеке. Переменные, помещаемые в этот тип памяти, иногда упоминаются как локальные, динамические или автоматические переменные. Листинг 2-8 представляет типичную последовательность событий, происходящих на входе типичных программ на языке высокого уровня. Процедура устанавливает новый блок данных (сохранение регистра BP и установка регистра BP в текущем SP), распределяет локальную память (вычитает из SP) и сохраняет регистры, которые она может разрушить.


Рис. 2-1 представляет структуру стека, как она выглядит внутри программы Example (пример), и показывает как шаблон Stackframe (блок данных стека) выравнивается вместе со стеком. Заметим, что выравнивание выполняется благодаря описанию базы как "[BP-offset XamplBP]". Т.к. XamplBP выровнен с ячейки сохраненного BP в стеке, то выбранное описание base.XamplBP эквивалентно [BP - offset XamplBP + offset XamplBP], а последнее есть то же самое, что [BP + 0]. Другим важным моментом является то, что структура шаблона стека должна начинаться с объявления таких элементов, которые будут размещаться в нижней памяти.


НАЗАД СОДЕРЖАНИЕ ВПЕРЁД

Hosted by uCoz