
- •Регистровая адресация
- •Непосредственная адресация
- •Прямая адресация (па)
- •Косвенная регистровая адресация (кра).
- •Адресация с базированием (аб)
- •Адресация с индексированием (аи).
- •Адресация с базированием и индексированием (аби)
- •Использование стека
- •Организация подпрограмм
- •Команды вызова подпрограмм
- •Команды возврата из подпрограмм
- •Директива процедуры
- •Передача параметров в подпрограмму
Адресация с индексированием (аи).
При адресации с индексированием ИА вычисляется как сумма значений сдвига и индексного регистра SI или DI. Этот тип адресации удобен для доступа к элементам таблицы, когда сдвиг указывает на начало таблицы, а индексный регистр на ее элемент.
Например, если BYTE_TABLE – таблица байтов, то последовательность команд
MOV DI , 2
MOV AL , BYTE_TABLE [DI]
загрузит в AL 3-й элемент таблицы.
В таблице слов соседние элементы отличаются друг от друга на 2 байта, при работе с ней надо удваивать номер элемента при вычислении значения индекса.
Если TABLE – таблица слов, то для загрузки в AX 3-го элемента надо воспользоваться следующим набором команд:
MOV DI , 4
MOV AX , TABLE [DI]
TABLE
[DI]
TABLE
01
DI 02
03
04
AX 05
06
Адресация с базированием и индексированием (аби)
При АБИ исполнительный адрес вычисляется как сумма значений базового регистра, индексного регистра и возможного смещения.
Т.к. в этом режиме складываются два отдельных смещения, то он удобен при адресации двумерных массивов, когда базовый регистр содержит начальный адрес массива, а значение сдвига и индексного регистра – есть смещение по строке и по столбцу.
MOV [BX+SI], AL
MOV [BX][SI], DL
MOV [BX+SI-1], CH
MOV 50000[BX][DI], AL
MOV MAS[BX][SI], AX
MOV MAS+10000[BX][DI], DX
Использование стека
Стек (stack) — важное понятие теоретического программирования, частный случай линейного списка. Это одномерная динамическая структура данных, добавление элемента в которую (или исключение элемента из которой) производится с одного конца, называемого вершиной стека (Top of Stack). Другими словами, стек организован в виде списка типа LIFO (Last In – First Out – «последний пришел – первый вышел»).
Стек размещается в ОЗУ, в стековом сегменте (т.е. сегментный адрес области памяти для стека хранится в SS). Элементы стека – слова. Нельзя поместить в стек данные размером в байт.
Регистр SP (Stack Pointer – указатель стека) содержит смещение последнего включенного в стек слова, т.е. SP указывает на вершину стека. При включении в стек новых слов вершина перемещается в направлении уменьшения адресов (говорят: стек растет вниз). Включение в стек (push) обозначают стрелкой, направленной вниз , извлечение из стека (pop) — стрелкой, направленной вверх . Перечислим команды для работы со стеком:
Поместить в стек |
push src |
|
PUSH |
флаги не изменяются |
Извлечь из стека |
pop dst |
1) dst (SP) 2) SP SP + 2 |
POP |
флаги не изменяются |
Поместить в стек флаги |
pushf |
flags |
PUSH Flags |
флаги не изменяются |
Извлечь из стека флаги |
popf |
flags |
POP Flags |
флаги из стека |
При записи в стек выполняются действия:
– SP:=SP-2;
– вычисление физического адреса памяти по содержимому регистров SS и SP, и запись в него слова.
При выборке из стека выполняются следующие действия:
– из вершины стека считывается слово;
– SP:=SP+2.
Значения, только что извлеченные из стека, пока еще сохраняются в области памяти стека, но при следующих операциях со стеком они будут уничтожены.
В 286-м процессоре появились две новые команды для работы со стеком.
Включить в стек все РОНы |
pusha |
ax cx dx bx sp bp si di |
PUSH All |
флаги не изменяются |
В стек помещается то содержимое SP, которое было в нем до выполнения команды pusha.
Извлечь из стека все РОНы |
popa |
di si bp sp bx dx cx ax |
POP All |
флаги не изменяются |
Эти две команды полезны, когда нужно сохранить и восстановить практически все регистры общего назначения. Если же нужно сохранить и восстановить только два-три регистра, то лучше для каждого из них использовать отдельную команду push и pop.
В ассемблерной программе размер стека задается в описании сегмента стека. Следующий пример иллюстрирует создание стека размером 1024 слова.
StackSG segment para STACK 'Stack'
dw 1024 dup (?)
StackSG Ends
Во время работы со стеком количество данных помещенных в стек, может превысить его размер. При этом будет происходить обращение к данным, расположенным за границей стека. Там обычно располагается сегмент данных, т.е. будет выбираться слово из поля какой-либо переменной. Такая ситуация называется переполнением стека и в ассемблерных программах может быть отслежена только программистом.
За заполнением стека в языках высокого уровня следит специальная система. При возникновении переполнения осуществляется прерывание программы и выдача сообщения 'stack overflow'.
Для правильной работы со стеком количество «погружений» и количество "всплытий" должно быть одинаково, и первой среди стековых команд должна быть команда PUSH.