Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000239.doc
Скачиваний:
23
Добавлен:
30.04.2022
Размер:
1.12 Mб
Скачать

6. Стек

6.1. Стек и сегмент стека

Стек – это хранилище, работа с которым ведется по следующему принципу: элемент, записанный в стек последним, считывается из него первым. В ПК для такого хранилища можно отвести любую область памяти, но к ней предъявляется два требования: ее размер не должен превышать 64 Кб и ее начальный адрес должен быть кратным 16. Другими словами, эта область должна быть сегментом памяти. Его называют сегментом стека. На его начало должен указывать сегментный регистр SS (рис. 32).

Рис. 32. Сегмент стека

В ПК принято заполнять стек снизу вверх: первый элемент записывается в самый конец области стека (в ячейку области с наибольшим адресом), следующий элемент записывается «над» ним и т. д. При чтении же из стека первым всегда удаляется самый верхний элемент. Поэтому получается, что низ стека фиксирован (это последняя ячейка области стека), а вот вершина стека все время сдвигается. Для того чтобы знать текущее положение этой вершины, используется еще один регистр – SP (stack pointer, указатель стека). В нем хранится адрес той ячейки, в которой находится элемент, записанный в стек последним. Более точно, в SP находится смещение этой ячейки, т. е. ее адрес, отсчитанный от начала сегмента стека. Поэтому абсолютный адрес вершины стека задается парой регистров SS:SP.

Элементы стека могут иметь любой размер; это могут быть байты, слова, двойные слова и т. д. Однако имеющиеся в ПК команды записи в стек и считывания из него работают только со словами. Поэтому обычно подстраиваются под эти команды и считают, что элементы стека имеют размер слова. Обработка же байтов и двойных слов подгоняется под обработку слов.

Следует различать термины «сегмент стека» и «стек (содержимое стека)»: если первый термин означает область памяти, которую потенциально могут занять данные стека, то второй термин обозначает совокупность тех данных, что в текущий момент хранятся в стеке, т. е. совокупность байтов от адреса из SP до конца сегмента стека. Причем все данные, расположенные «выше» адреса из SP, считаются не относящимися к стеку.

Чтобы зарезервировать место в памяти под стек, в программе на языке ассемблера следует описать соответствующий программный сегмент. Если мы решили выделить под него к байтов, тогда этот сегмент должен описываться так:

S SEGMENT STACK

DB k DUP(?)

S ENDS

Имена ячейкам стека обычно не дают, т. к. доступ к ним все равно будет осуществляться не по именам, а косвенно, через регистр SP. Чаще всего не задают и начальные значения для ячеек стека. Поэтому при описании сегмента стека указывают лишь то, сколько байтов отводится под стек, т. е. используют безымянную директиву DB со знаком ?. Отметим, что вместо директивы DB можно использовать директиву DW или DD, это как кому нравится.

Прежде чем начать работу со стеком, надо загрузить в регистры SS и SP соответствующие значения: регистр SS должен указывать на начало сегмента стека, а регистр SP – на вершину стека. Сделать это можно двояко. Во-первых, такую загрузку мы можем сделать сами, поместив в программу соответствующие команды. Во-вторых, если в директиве SEGMENT, начинающей описание сегмента стека, указать параметр STACK, тогда к началу выполнения программы оба этих регистра будут загружены автоматически: регистр SS будет установлен на начало сегмента стека, а в регистр SP будет записан размер стека в байтах (число k). Почему именно это значение? В начале работы программы стек должен быть, как правило, пустым, а значение k, как несложно сообразить, как раз и соответствует пустому стеку; в этом случае SP указывает на первую ячейку за областью стека.

И, наконец, напомним, что сегмент стека надо описывать в программе даже тогда, когда программа сама его не использует. В таком случае рекомендуемый размер (с запасом) сегмента стека – 128 байтов. Если же программа сама использует стек, то под него надо отводить столько места, сколько надо программе, плюс эти 128 байтов.