Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
5iOGKCvhPS.file.doc
Скачиваний:
7
Добавлен:
30.04.2022
Размер:
283.14 Кб
Скачать

2.2.2. Стековые команды

Основными стековыми командами являются команды записи слова в стек и чтении слова из стека.

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

Запись в стек осуществляется с помощью следующей команды

PUSH op

Допустимые типы операнда:

– регистр общего назначения 16 бит;

– сегментный регистр;

– слово памяти.

Команда PUSH действует следующим образом: сначала значение регистра SP уменьшается на 2 (вычитание происходит по модулю 216), т.е. SP сдвигается вверх и теперь указывает на свободную ячейку стека, а затем в нее записывается операнд.

SP := (SP - 2) mod 216, op -> [SS:SP]

Непосредственный операнд в данной команде указывать нельзя (такой формат появился только в процессоре I80186). Если необходимо записать в стек число , то это необходимо сделать через регистр, например:

MOV AX, 5

PUSH AX

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

Например, необходимо записать в стек символ ‘*’:

MOV AL, ‘*’ ;AL:=’*’ AH:=?

PUSH AX

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

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

Чтение слова из стека осуществляется с помощью следующей команды:

POP op

Допустимые типы операнда:

– регистр общего назначения 16 бит;

– сегментный регистр (кроме CS – изменение этого регистра означает переход к следующей команде);

– слово памяти.

Команда POP считывает слово из вершины стека и присваивает ее указанному операнду. Она действует следующим образом: слово из ячейки, на которую указывает пара SS:SP, пересылается в операнд, а затем SP увеличивается на 2 (сложение происходит по модулю 216), т.е. сдвигается вниз:

[SS:SP] -> op, SP:=(SP+2) mod 216.

2.2.3 Приемы работы со стеком

Сохранение значений регистра

Если необходимо сохранить текущее значение какого-нибудь регистра (но в то же время регистр требуется использовать для какой-либо цели, после чего его надо вернуть в исходное состояние), то можно поступить следующим образом: записать в стек значение регистра, затем использовать регистр как нужно, а в конце восстановить прежнее значение регистра, считав его из стека:

PUSH CX

… ; использование CX

POP CX

Пересылка данных через стек

Стек можно использовать для пересылки какой-нибудь величины из одной ячейки в другую, когда нет возможности использовать регистры. Например, выполнить присваивание X:=Y, где X и Y – переменные размером в слово.

PUSH Y

POP X ;X := Y

Проверка на выход за пределы стека

Команды PUSH и POP не осуществляют проверку на выход за пределы стека. Если применяется команда считывания из стека, а стек при этом пуст – ошибка не фиксируется (будет считано слово, следующее за пределами стека). Также не будет зафиксирована ошибка при попытке записать значение в стек, когда он полон. Такие проверки необходимо делать программно:

CMP SP, 0 ; Проверка – стек полон?

CMP SP, k ; Проверка – Стек пуст (в стеке k байт)?

Иначе говоря, стек полон, если вершина стека достигла начала области, выделенной для стека, а это значит, что смещение вершины стека равно 0. При пустом стеке в регистре SP находится число, равное размеру области в байтах.

Очистка и восстановление стека

Если необходимо очистить стек сразу от N значений, то можно просто увеличить значение регистра SP на нужную величину. Учитывая, что каждый элемент стека занимает слово (2 байта), очистка стека от N слов будет выглядеть следующим образом:

ADD SP, 2*N ;очистка стека от N слов

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

MOV AX, SP

... ;записи в стек

MOV SP, AX

Доступ к элементам стека. Регистр BP.

Команды PUSH и POP дают доступ только к вершине стека, но иногда необходим доступ к другим, более "низким" элементам стека. Для этого необходимо использовать косвенную адресацию по регистру-модификатору BP.

Сначала следует записать в BP адрес какого-либо элемента стека, например, вершины:

MOV BP, SP

Теперь команда

MOV AX, [BP]

поместит в AX содержимое последней ячейки стека. Команда

MOV AX, [BP+2]

Поместит в AX содержимое предпоследней ячейки (ее адрес равен адресу вершины стека плюс 2), а команда

MOV AX,[BP+4]

– содержимое третьей с конца ячейки и т.д.

Регистр BP выбран для адресации доступа специально. Регистр SP нельзя использовать, таким образом, т.к. SP не относится к регистрам-модификаторам (т.е. выражение [SP+4] будет ошибкой). Также, если в качестве регистра модификатора используется BP, по умолчанию в качестве сегментного регистра при определении абсолютного физического адреса будет использоваться регистр SS (т.е. в команде его можно не указывать). Если использовать другой регистр модификатор, то регистр SS следует указывать явно, например:

MOV AX, SS:[BX+4]

Таким образом, вариант с регистром BP более удобен.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]