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 Подпрограммы
Типичная схема огранизации подпрограмм, обычно используемая транс-
ляторами с языков высокого уровня для реализации процедур и функций (в
частности, рекурсивных), следующая.
При обращении к подпрог