Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / Лекция 3 / Лекция 3.doc
Скачиваний:
28
Добавлен:
10.06.2015
Размер:
123.9 Кб
Скачать

Работа со стеком

Стек — это область памяти, специально выделяемая для временного хранения данных программы. Важность стека определяется тем, что для него в структуре программы предусмотрен отдельный сегмент. На тот случай, если программист забыл описать сегмент стека в своей программе, компоновщик tlink выдаст предупреждающее сообщение.

Для работы со стеком предназначены три регистра:

SS — регистр сегмента стека;

SP/ESP — регистр указателя стека;

ВР/ЕВР — регистр указателя базы кадра стека.

Размер стека зависит от режима работы процессора и ограничивается значением 64 Кбайт (или 4 Гбайт в защищенном режиме). В каждый момент времени доступен только один стек, адрес сегмента которого содержится в регистре SS. Этот стек называется текущим. Для того чтобы обратиться к другому стеку («переключить стек»), необходимо загрузить в регистр SS другой адрес. Регистр SS автоматически используется процессором для выполнения всех команд, работающих со стеком.

Перечислим еще некоторые особенности работы со стеком.

- Запись и чтение данных в стеке осуществляются в соответствии с принципом

LIFO (Last In First Out — «последним пришел, первым ушел»).

- По мере записи данных в стек последний растет в сторону младших адресов. Эта особенность заложена в алгоритм команд работы со стеком.

-При использовании регистров ESP/SP и ЕВР/ВР для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра SS.

Регистры SS, ESP/SP и ЕВР/ВР используются комплексно, и каждый из них имеет свое функциональное назначение. Регистр ESP/SP всегда указывает на вершину тека, то есть содержит смещение, по которому в стек был занесен последний элемент. Команды работы со стеком неявно изменяют этот регистр так, чтобы он указывал всегда на последний записанный в стек элемент. Если стек пуст, то значение SP равно адресу последнего байта сегмента, выделенного под стек. При занесении элемента в стек процессор уменьшает значение регистра ESP, а затем записывает элемент по адресу новой вершины. При извлечении данных из стека процессор оперирует элемент, расположенный по адресу вершины, а затем увеличивает значение регистра указателя стека ESP. Таким образом, получается, что стек растет вниз, сторону уменьшения адресов.

Что нужно сделать для получения доступа к элементам не на вершине, а внутри тека? Для этого применяют регистр ЕВР. Регистр ЕВР — регистр указателя базы кадра стека. Например, типичным приемом при входе в подпрограмму является передача нужных параметров путем записи их в стек. Если подпрограмма тоже активно работает со стеком, то доступ к этим параметрам становится проблематичным. Выход в том, чтобы после записи нужных данных в стек сохранить адрес вершины стека в указателе базы кадра стека — регистре ЕВР. Значение в ЕВР в дальнейшем можно использовать для доступа к переданным параметрам.

Начало стека расположено в старших адресах памяти.К примеру, для программы из листинга 7.1 началу стека будет соответствовать пара SS:0100h. Адресная пара SS:ffff — это максимальное для реального режима значение адреса начала стека, так как размер сегмента в нем ограничен величиной 64 Кбайт (Offffh).

Для организации работы со стеком существуют специальные команды записи и чтения.

Команда PUSH выполняет запись значения <источник> в вершину стека:

push <источник>

Интерес представляет алгоритм работы этой команды, который включает два

действия:

1. Значение SP уменьшается на 2:

(SP) = (SP) - 2

2. Значение источника записывается по адресу, указываемому парой SS:SP.

Команда POP выполняет запись значения из вершины стека по месту, указанному операндом <приемник> (значение при этом «снимается» с вершины стека):

pop <приемник>

Алгоритм работы команды POP обратен алгоритму команды PUSH.

1. Запись содержимого вершины стека по месту, указанному операндом <приемник>.

2. Увеличение значения SP:

(SP) = (SP) + 2

Команда PUSHA предназначена для групповой записи в стек. По этой команде в стек последовательно записывается содержимое регистров АХ, СХ, DX, BX, SP, BP, SI, DI. Заметим, что записывается оригинальное содержимое SP, то есть то, которое было до выдачи команды PUSHA.

Команда PUSHAW почти идентична команде PUSHA. В чем разница? В главе 5 мы обсуждали один из атрибутов сегмента — атрибут размера сегмента. Он может принимать значения use16 или use32:

-use!6 — алгоритм работы PUSHAW аналогичен алгоритму PUSHA;

-use32 — алгоритм работы команды PUSHAW не меняется (то есть она нечувствительна к разрядности сегмента и всегда работает с регистрами размером в слово — АХ, СХ, DX, BX, SP, BP, SI, DI), а команда PUSHA чувствительна к разрядности сегмента и при указании 32-разрядного сегмента работает с соответствующими 32-разрядными регистрами (то есть ЕАХ, ЕСХ, EDX, EBX, ESP, EBP, ESI, EDI).

Команда PUSHAD — выполняется аналогично команде PUSHA, но есть некоторые особенности, которые вы можете найти в приложении.

Следующие три команды выполняют действия, обратные действиям описанных ранее команд:

РОРА;

POPAW;

POPAD.

Представленная далее группа команд позволяет сохранить в стеке регистр флагов и записать слово или двойное слово. Отметим, что перечисленные команды —единственные в системе команд процессора, которые позволяют получить доступ (и которые нуждаются в этом доступе) ко всему содержимому регистра флагов.

Команда PUSH F сохраняет регистр флагов в стеке. Работа этой команды зависит от атрибута размера сегмента:

use 16 — в стек записывается регистр FLAGS размером два байта;

use3 2 — в стек записывается регистр Е FLAGS размером четыре байта.

Команда PUSHFW сохраняет в стеке регистр флагов размером в слово. С атрибутом use16 всегда работает так же, как команда PUSHF.

Команда PUSHFD сохраняет в стеке регистр флагов FLAGS или EFLAGS в зависимости от атрибута размера сегмента (то есть то же, что и PUSHF).

Следующие три команды также выполняют действия, обратные действиям рассмотренных выше команд:

POPF;

POPFW;

POPFD.

Работать со стеком приходится постоянно, поэтому к этому вопросу мы будем возвращаться еще не раз. Отметим основные виды операций, когда использование стека практически неизбежно:

-вызов подпрограмм;

- временное сохранение значений регистров;

-определение локальных переменных в процедуре.

Итоги

Основная команда пересылки данных — MOV. Операнды этой команды (как и большинства других команд, берущих значения из памяти) должны быть согласованы по разрядности. Хотя обычно действуют правила умолчания, в сомнительных ситуациях лучше явно указывать разрядность операндов с помощью оператора PTR.

Управление периферией компьютера в общем случае осуществляется с использованием всего двух команд ввода-вывода — IN и OUT.

В процессе работы программы динамически можно получить как эффективный, так и полный (физический) адрес памяти. Для этого язык ассемблера предоставляет группу команд получения указателей памяти.

Архитектура процессора предоставляет в распоряжение программиста специфическую, но весьма эффективную структуру — стек. Система команд поддерживает все необходимые операции со стеком. Подробнее со стеком мы познакомимся при изучении модульного программирования на ассемблере

Соседние файлы в папке Лекция 3