Ассемблер: взгляд издалека.
Продолжение.
Начало в || 20, 21, 24, 25, 28
{}Инфарх, 1999
Что такое стек?
Наверняка вы уже слышали это слово. По-
пробуем выяснить, что скрывается за ним.
"Стеком" называют память, при работе с
которой используется принцип, именуемый
"first in, last out (первым вошёл, послед-
ним вышел)". Это означает, что данные
(слова) заносятся на стек последовательно,
одно за другим, и считываются с него в об-
ратном порядке. При этом доступ возможен
только к так называемой "вершине стека",
т.е. к последнему помещённому туда слову.
Стек предназначен для хранения процессо-
ром временных данных, таких, в частности,
как адреса возврата из подпрограмм.
В процессоре Z80 за размещением информа-
ции в стеке следит регистр SP, в котором
сохраняется адрес вершины стека. Отметим
один важный момент: при занесении очеред-
ного слова в стек адрес его вершины смеща-
ется вниз (к младшим адресам), т.е. не
увеличивается, а уменьшается. Таким обра-
зом, если в SP у вас записан адрес #6000,
то следующее слово, помещённое на стек,
разместится в памяти по адресу не #6002, a
#5FFE. Так стек адресуется в большинстве
микропроцессорных систем (но, конечно, нет
правил без исключений...)
Определение области стека
Конечно, с областью, отведённой под
стек, можно работать, как и с любой другой
областью памяти. Но, используя специальные
команды процессора, предназначенные для
работы со стеком, можно значительно уско-
рить и упростить работу программы.
Как же использовать стек?
Для начала надо позаботиться о записи в
SP адреса вершины стека. Команды здесь
выглядят так:
LD SP,(addr)
LD SP,IX
LD SP,IY
LD SP,HL
LD SP,nn
Влияния на флаги это не оказывает. А
после одного из вышеприведённых действий в
SP окажется желаемое значение. Но если вам
этого недостаточно, то можно использовать
следующие действия:
INC SP
DEC SP
Тем самым вы уж точно сможете придать SP
требуемое значение. А если говорить о вли-
янии на флаги, то ничего необычного здесь
тоже не происходит. Всё в пределах того
типа команд, которые используются в опера-
ции.
Работа со стеком
В самом простом варианте на стеке можно
размещать информацию и, естественно, полу-
чать её оттуда.
Итак, размещение. Для этого мы использу-
ем команду "PUSH" в следующих вариантах:
PUSH rr
PUSH ii
Как и принято у нас, "rr" обозначает ре-
гистровую пару, а "ii" - индексный регистр
IX или IY. Когда процессор столкнётся с
суровой необходимостью выполнить такую ко-
манду, то первым делом уменьшит содержа-
щийся в SP адрес на два. После этого по
получившемуся адресу будет переслано со-
держимое регистровой пары, указанной после
"PUSH". Таким методом мы можем сохранять
на стеке данные.
А как их оттуда снимать? Тоже очень
просто. Команда, обратная "PUSH", записы-
вается как "POP". Запись её полностью ана-
логична вышеописанной:
POP rr
POP ii
Выполняя эту команду, процессор возьмёт
слово, адрес которого хранится в SP, и по-
местит его в регистровую пару, указанную в
команде, после чего содержимое SP будет
увеличено на два. На будущее давайте дого-
воримся: если вам встретится фраза типа
"поместить на стек" или "снять со стека",
то подразумевается и естественная коррек-
ция содержимого SP. И ещё один совет: при
работе со стеком не забывайте, в какой
последовательности вы помещали в него дан-
ные, иначе ваша программа рискует уподо-
биться Windows'95!
А вот ещё несколько команд для работы со
стеком:
EX (SP),HL
EX (SP),IX
EX (SP),IY
По ним происходит обмен между содежимым
вершины стека и содержимым HL или ин-
дексного регистра;
ADC HL,SP
ADD HL,SP
ADD IX,SP
ADD IY,SP
Применяя их, значение SP можно использо-
вать в некоторых видах вычислений.
А теперь - о флагах. Как "PUSH", "POP",
так и "EX" никакого влияния на флаги не
оказывают, но... если вы выполните команду
"POP AF", то, естественно, флаги будут уже
далеко не те, так что не забывайте об
этом! А что касается арифметических
действий, то там воздействие на флаги тоже
вполне обычное и соответствует прочим
арифметическим операциям.
Подпрограммы
Для начала определимся с терминологией.
"Подпрограммой" называют фрамент основной
программы, который может быть вызван из
любого места оной для выполнения опре-
делённой задачи, после отработки которой
управление возвращается основной программе
с того места, откуда была вызвана подпрог-
рамма. Для её вызова используется команда
"CALL", запись которой может принимать
следующие формы:
CALL addr
CALL cc,addr
Надеюсь, вы не забыли, что "cc" обозна-
чает возможность использования условия. А
условия допускаются такие:
C, M, NC, NZ, P, PE, PO, Z
Как водится, выполняется команда "CALL"
не просто, а очень просто. Встретив её,
процессор поместит на стек адрес команды,
следующей за "CALL". После этого управле-
ние будет передано тому фрагмету програм-
мы, который расположен по адресу "addr".
Вот так и произойдёт вызов подпрограммы. А
как вернуться из неё? И того проще!
Подпрограмма должна заканчиваться командой
"RET", встретив которую, процессор снимет
с вершины стека слово для использования
его в качестве адреса перехода. Если вы
ничего со стеком не начудили, этим словом
будет адрес, помещённый туда командой
"CALL".
Теперь вам понятно упоминание в одном из
первых наших занятий команды "RET"? Дело в
том, что когда вы запускаете програму из
Ассемблера, он выполняет её как подпро-
грамму, и, что естественно, рассчитывает
на корректный выход.
И напоследок - о вариантах написания ко-
манды "RET":
RET
RET cc
Вот и все сложности! Даже адрес не надо
указывать. Условия здесь тоже возможны.
Они полностью аналогичны тем, что ис-
пользует команда "CALL".
Неужели всё???
А вот и нет! Осталась ещё одна команда,
вполне подходящая к теме сегодняшнего за-
нятия. Это так называемый "вызов рестар-
та".
Рестарт - это почти то же самое, что и
"CALL", но он позволяет совершать вызов
только восьми процедур, расположенных в
первых 256 байтах памяти:
#00, #08, #10, #18, #20, #28, #30, #38
Преимуществом команды рестарта (RST) яв-
ляется то, что она занимает всего один
байт и срабатывает быстрее, чем "CALL". А
недостатком - то, что применить её можно
только для обращения к одной из восьми
приведённых выше ячеек. В Спектруме все
эти адреса относятся к ПЗУ, но если вы
знаете, что они делают, то можете ис-
пользовать их в своих программах.
Варианты записи команд рестарта следую-
щие:
RST #00
RST #08
RST #10
RST #18
RST #20
RST #28
RST #30
RST #38
Небольшое примечание
Итак, со стеком мы разобрались.
Добавлю ещё пару слов. Электронная газе-
та "Полесье" тоже приступила к публикации
заметок типа нашего "Ликбеза". Так что,
если заинтересуетесь - обращайтесь и к
этому изданию за дополнительной информаци-
ей.
Вот и всё на сегодня. Не бойтесь экспе-
риментировать, ведь "на глюках учатся"! До
новых встреч!
Продолжение следует...
──══════════──