- •1.2.2. Команды управления циклом
- •1.2.3. Работа с массивами
- •1.3. Задание на лабораторную работу
- •1.4. Отчет по лабораторной работе
- •2. Лабораторная работа № 4
- •2.1. Общие методические указания по выполнению лабораторной работы
- •2.2. Теоретические сведения
- •2.2.1. Стек и сегмент стека
- •2.2.2. Стековые команды
- •2.2.3 Приемы работы со стеком
- •2.3. Задание на лабораторную работу
- •2.4. Отчет по лабораторной работе
- •3 .Лабораторная работа № 5
- •3.1. Общие методические указания по выполнению лабораторной работы
- •3.2. Теоретические сведения
- •3.2.1. Дальние переходы
- •3.2.2. Подпрограммы (процедуры)
- •3.3. Задание на лабораторную работу
- •3.4. Отчет по лабораторной работе
- •4. Лабораторная работа №6.
- •4.1. Общие методические указания по выполнению лабораторной работы
- •4.2. Теоретические сведения
- •4.3.Задание на лабораторную работу
- •4.4. Отчет по лабораторной работе
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 более удобен.