IBM PC

Информация - Компьютеры, программирование

Другие материалы по предмету Компьютеры, программирование

:SP | | SS:SP | | SS:SP | |

| ----- запись | ----- чтение | -----

| | | =======> ---->| b | =======> | | |

| ----- в стек ----- из стека | -----

----->| a | | a | ---->| a |

----- ----- -----

Значение 0 в регистре SP свидетельствует о том, что стек полностью

заполнен (его вершина "дошла" до начала области стека). Поэтому для

контроля за переполнением стека надо перед новой записью в стек прове-

рять условие SP=0 (сам ПК этого не делает). Для пустого стека значение

SP должно равняться размеру стека, т.е. пара SS:SP должна указывать на

байт, следующий за последним байтом области стека. Контроль за чтением

из пустого стека, если надо, обязана делать сама программа.

Начальная установка регистров SS и SP может быть произведена в са-

мой программе, однако в MASM предусмотрена возможность автоматической

загрузки этих регистров. Если в директиве SEGMENT, начинающей описание

сегмента стека, указать параметр STACK, тогда ассемблер (точнее, за-

грузчик) перед тем, как передать управление на первую команду машинной

программы, загрузит в регистры SS и SP нужные значения. Например, если

в программе сегмент стека описан следующим образом:

ST SEGMENT STACK

DB 256 DUP(?) ;размер стека - 256 байтов

ST ENDS

и если под этот сегмент была выделена область памяти начиная с абсо-

лютного адреса 12340h, тогда к началу выполнения программы в регистре

SS окажется величина 1234h, а в регистре SP - величина 100h (=256).

Отметим, что эти значения соответствуют пустому стеку.

1.7.2 Основные стековые команды

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

команды, предназначенные для работы со стеком. Основными из них явля-

ются следующие.

Запись слова в стек: PUSH op

Здесь op обозначает любой 16-битовый регистр (в том числе и сегмент-

ный) или адрес слова памяти. По этой команде значение регистра SP

уменьшается на 2 (вычитание происходит по модулю 2^16), после чего

указанное операндом слово записывается в cтек по адресу SS:SP.

Чтение слова из стека: POP op

Слово, считанное из вершины стека, присваивается операнду op (регист-

ру, в том числе сегментному, но не CS, или слову памяти), после чего

значение SP увеличивается на 2.

Переход с возвратом: CALL op

Эта команда записывает адрес следующей за ней команды в стек и затем

делает переход по адресу, определяемому операндом op. Она используется

для переходов на подпрограммы с запоминанием в стеке адреса возврата.

Имеются следующие разновидности этой команды (они аналогичны вари-

антам команды безусловного перехода JMP):

- внутрисегментный относительный длинный переход (op - непосредст-

венный операнд размером в слово, а в MASM - это метка из текущего сег-

мента команд или имя близкой процедуры (см. ниже)); в этом случае в

стек заносится только текущее значение счетчика команд IP, т.е. смеще-

ние следующей команды;

- внутрисегментный абсолютный косвенный переход (op - адрес слова

памяти, в которой находится адрес (смещение) той команды, на которую и

будет сделан переход); и здесь в стек записывается только смещение ад-

реса возврата;

- межсегментный абсолютный прямой переход (op - непосредственный

операнд вида seg:ofs, а в MASM - это FAR PTR или имя дальней

процедуры (см. ниже)); здесь в стек заносится текущие значение регист-

ров CS и IP (первым в стек записывается содержимое CS), т.е. абсолют-

ный адрес возврата, после чего меняются регистры CS и IP;

- межсегментный абсолютный косвенный переход (op - адрес двойного

слова, в котором находится пара seg:ofs, задающая абсолютный адрес пе-

рехода); и здесь в стеке спасается содержимое регистров CS и IP.

Переход (возврат) по адресу из стека: RET op

Из стека считывается адрес и по нему производится переход. Если указан

операнд (а это должно быть неотрицательное число), то после чтения ад-

реса стек еще очищается на это число байтов (к SP добавляется это чис-

ло). Команда используется для возврата из подпрограммы по адресу, за-

писанному в стек по команде CALL при вызове подпрограммы, и одновре-

менной очистки стека от параметров, которые основная программа занесла

в стек перед обращением к подпрограмме.

Команда RET имеет две разновидности (хотя в MASM они записываются

и одинаково): в одном случае из стека считывается только одно слово -

смещение адреса возврата, а во втором - из стека считывается пара seg:

ofs, указывающая абсолютный адрес возврата. Как ассемблер определяет,

какой из этих двух случаев имеет место, объяснено ниже.

В ПК стек в основном используется для организации подпрограмм и

прерываний. Подпрограммы рассматриваются ниже, а прерывания - в главе

3. Однако, даже если программе не нужен стек, она все равно должна от-

вести под него место. Дело в том, что стеком будет неявно пользоваться

операционная система при обработке прерываний, которые возникают (нап-

ример, при нажатии клавиш на клавиатуре) в то время, когда выполняется

программа. Для нужд ОС рекомендуется выделять в стеке 64 байта.

1.7.3 Подпрограммы

Типичная схема огранизации подпрограмм, обычно используемая транс-

ляторами с языков высокого уровня для реализации процедур и функций (в

частности, рекурсивных), следующая.

При обращении к подпрог