Типичные приемы работы со стеком. В связи с ограниченным количеством регистров общего назначения стек используется для временного хранения содержимого регистров. Когда регистр, например AX, необходим для работы, его текущее значение может быть помещено в стек. После работы с регистром, прежнее значение должно быть восстановлено:
PUSH AX
... ; использование AX
POP AX
Наряду с сохранением данных стек может быть применен в роли буфера при пересылках чисел из одной ячейки памяти в другую, когда не следует изменять содержимое регистров. Например, присваивание переменных размером в слово X:=Y можно определить так:
PUSH Y
POP X
Такая схема удобна при переносе содержимого одного сегментного регистра в другой. Обычно загрузка одного сегментного регистра из другого требует сначала загрузки его значения в промежуточный регистр:
MOV AX, CS
MOV DS, AX
Каждая из команд имеет длину в несколько байт, и разрушает содержимое AX. Альтернативой может быть последовательность:
PUSH CS
POP DS
Команды в памяти занимают два байта, однако, они исполняются дольше, т.к. требуются дополнительные циклы чтения-записи в стек.
Стековые команды не осуществляют проверку на выход за пределы стека. Например, если стек пуст и применяется команда чтения из стека, то ошибка не будет зафиксирована (будет считано слово, следующее за сегментом стека). Стек полон, когда вершина стека достигла начала области, выделенной для стека, т.е. смещение вершины стека равно 0. При пустом стеке в регистре SP находится число, равное размеру области стека в байтах:
SP = 0 - стек полон
SP = k - стек пуст
Для очистки стека существует несколько вариантов действий. Можно выполнить команду POP заданное число. Оптимальным решением будет увеличение значения регистра SP на 2*N:
ADD SP, 2*N ; очистка стека от N слов
Еще один вариант очистки стека следующий: запомнить вначале значение указателя стека SP, до которого затем надо будет очищать стек, после чего производить запись в стек, а в конце восстановить в SP это значение:
MOV AX, SP
... ; записи в стек
MOV SP, AX
Команды PUSH и POP предоставляют доступ к вершине стека, но иногда необходим доступ к более «глубоким» элементам стека (рис. 22). Пусть в стеке записано три слова и требуется переслать в регистр АХ копию третьего сверху элемента стека (AX = w3). Смещение третьего слова стека равно 4, поэтому следует установить регистр ВР на вершину стека и использовать выражение [ВР+4]:
MOV BP, SP
MOV АХ, [ВР+4]
Поскольку доступ к внутренним элементам стека приходиться делать довольно часто, регистр ВР выделен особо и по умолчанию сегментируется по SS. Использовать регистр SP, т.е. выражение [SP+n], нельзя, т.к. SP не относится к числу регистров-модификаторов.
Напомним, что если в команде модифицируется адрес и среди модификаторов есть регистр ВР, по умолчанию выбирается регистр SS. Поэтому указанная команда транслируется как MOV AX, SS:[BP+n], и, следовательно, считывание будет происходить из сегмента стека. Если вместо ВР используется другой регистр-модификатор, например ВХ, тогда префикс должен быть указан явно: MOV AX, SS:[BX+n].
Рис. 22. Содержимое стека.
Do'stlaringiz bilan baham: |