Команды работы со стеком

Стек (англ. stack – стопка) – это упорядоченная область памяти, запись и чтение в которой осуществляется по принципу LIFO (Last In, First Out) – «последним пришел, первым ушел» или по принципу FILO (First In, Last Out) – «первым пришел, последним ушел».

Для работы со стеком в МП имеются специальные регистры: SS – сегментный регистр стека, SP – регистр указателя стека и BP – регистр указателя базы кадра стека. Стек занимает отдельный сегмент стека (для EXE-программ) или располагается в сегменте кода (для COM-программ) и не может превышать 64 Кбайт.

Схема организации стека показана на рис.7.5.

Команды работы со стеком - student2.ru

Рис. 7.5. Схема организации стека

Сегмент стека адресуется относительно регистра SS, в который заносится адрес начала этого сегмента. Шириной стека называется размер элементов, которые можно помещать или извлекать из него. Она составляет 16 бит или 2 байта, или 1 слово. В отличие от остальных сегментов, которые растут сверху вниз (от меньших адресов к большим), сегмент стека при записи в него информации растет снизу вверх (от больших адресов к меньшим). Наибольший адрес стека называется его дном (в предельном случае, если стек занимает весь сегмент, то дно имеет смещение FFFFH). Регистр SP указывает на вершину стека, то есть содержит смещение, по которому в стек был занесен последний элемент.

В COM-программах стек начинается с конца сегмента кода.

В микропроцессорах Intel существуют специальные команды для работы со стеком. Для добавления элемента на вершину стека используется команда PUSH (от англ. PUSH – толкать). Формат команды показан на рис.7.6.

Команды работы со стеком - student2.ru

Рис. 7.6. Формат команды PUSH

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

При выполнении данной команды:

– значение в регистре SP уменьшается на 2 (ширина стека 2 байта);

– операнд из источника копируется в память по физическому адресу SS:SP.

Примеры записи команды:

PUSH -5 ;Поместить -5 в стек

PUSH AX ;Поместить значение регистра AX в стек

PUSH DS ;Поместить значение регистра DS в стек

PUSH word ptr [BX] ;Поместить в стек слово по смещению, хранящемуся в ;регистре BX

Существуют еще две команды для записи данных в стек. Команда PUSHF помещает в стек содержимое регистра флагов. Команда PUSHA помещает в стек содержимое всех регистров общего назначения в следующем порядке: АХ, СХ, DX, ВХ, SP, BP, SI, DI (значение DI будет на вершине стека). Значение регистра SP помещается то, которое было до выполнения команды. Обе эти команды не имеют операндов.

Извлечение элемента из стека выполняется командой POP (от англ. POP – вытолкнуть). Формат команды показан на рис.7.7.

Команды работы со стеком - student2.ru

Рис. 7.7. Формат команды POP

У этой команды также один операнд, который может быть 16-битным регистром (в том числе сегментым, но кроме регистра CS) или 16-битной переменной в памяти. На состояние флагов выполнение команды влияния не оказывает.

При выполнении команды:

– операнд копируется из памяти по физическому адресу SS:SP в приемник;

– значение в регистре SP увеличивается на 2.

Примеры записи команды:

POP CX ;Поместить значение из вершины стека в регистр CX

POP ES ;Поместить значение вершины из стека в регистр ES

POP word ptr [DI] ;Поместить значение из вершины стека в слово по смещению, ;хранящемуся в регистре DI

Следующая последовательность команд реализует обмен значениями между двумя регистрами AH и BL:

PUSH AH

PUSH BL

POP AH

POP BL

Существуют еще две команды для чтения из стека. POPF помещает значение с вершины стека в регистр флагов. POPA восстанавливает из стека все регистры общего назначения (но при этом значение для SP игнорируется) в следующем порядке: DI, SI, BP, SP, BX, DX, CX, AX.

Для произвольного доступа к элементам стека удобно использовать регистр указателя базы кадра стека BP. Пусть необходимо записать в регистр AX, третий элемент стека, считая от вершины. Эффективный адрес третьего слова в стеке очевидно равен SP+4, тогда

MOV BP,SP

MOV AX,[BP+4]; то же самое MOV AX,SS:[BP+4]

Регистр BP в отличие от регистра SP может использоваться для модификации адреса. Кроме того при использовании регистра BP по умолчанию в качестве сегментного регистра как раз используется сегментный регистр стека SS, который можно в этом случае явно не указывать.

Вопросы для самопроверки

1. Определить значения регистров AX и BX после выполнения команд:

perem DW 1234H

MOV AX,perem

MOV BH,byte ptr perem

MOV BL,byte ptr perem+1

2. Написать фрагмент программы, который обменяет местами оба слова двойного слова perem:

perem DD 8B24EEFAH

3. Написать фрагмент кода для обмена значениями между регистрами CX и DX, используя стек.

4. Написать фрагмент кода для записи в регистр CX девятого элемента стека, считая от вершины.

5. В каком из регистров AH или AL находится большее значение при выполнении данного фрагмента программы?

field DB 25,12,28,41

MOV AL,field

LEA BX,field

INC BX

INC BX

MOV AH,[BX]

6. Написать фрагмент кода для записи в регистр AX регистра флагов.

7. Что будет храниться в регистре AX при выполнении данного кода?

perem DB 23,41,16,10

MOV AL,perem+1

MOV AH,perem+3

Наши рекомендации