Ликбез - Ассемблер взгляд издалека: Команды единичного приращения, прямой и относительный переход, организация цикла.
Ассемблер: взгляд издалека.
Продолжение. Начало в ||20, 21, 24, 25
{}Инфарх, 1999
Команды единичного приращения
В самой первой статье нашего "Ликбекза"
как пример команды Ассемблера упоминалась
команда приращения INC. Настало время
вплотную заняться ею, а также её "напарни-
цей" - командой DEC (от англ."decrement" -
многократное уменьшение значения перемен-
ной на заданную постоянную величину).
Никак нельзя приуменьшить их важности!
Ведь если вам вдруг понадобится увеличить
или уменьшить содержимое некоего регистра
или регистровой пары на единицу, то что
делать: работать с арифметическими
действиями? Упаси Господь!
И здесь нам на помощь приходят эти самые
команды положительного и отрицательного
единичного приращения. Рассмотрим варианты
их использования, не забыв и о флагах:
╔═════════════╤═══════════════════╗
║ МНЕМОНИКА │Разряды регистра F ║
║ │ (флаги) ║
╟────┬────────┼───────────────────╢
║Опе-│ │ ║
║ ра-│Операнд │ C Z P/V S N H ║
║ ция│ │ ║
╟────┴────────┼───────────────────╢
║ DEC r │ . x V x 1 x ║
║ DEC (HL) │ ║
║ DEC (ii+n) │ ║
║ DEC rr │ . . . . . . ║
║ DEC ii │ ║
║ │ ║
║ INC r │ . x V x 0 x ║
║ INC (HL) │ ║
║ INC (ii+n) │ ║
║ INC rr │ . . . . . . ║
║ INC ii │ ║
╚═════════════╧═══════════════════╝
Обозначения - аналогично предыдущим
статьям "Ликбеза".
Хоть команда и предельно проста, рассмо-
трим пример. Перед вами - фрагмент прог-
раммы:
LD A,5
LD HL,#C000
LD (HL),A
INC HL
DEC A
LD (HL),A
Первые три строки понятны: в "А" записы-
вется число 5, в регистровую пару "HL" -
число #C000. Затем происходит пересылка
содержимого "А" по адресу (HL), после чего
содержимое байта по адресу #C000 равно пя-
ти.
Следующая строка содержит команду "INC
HL", после выполнения которой в "HL" будет
уже число #C001. Соответственно, после
"DEC A" в аккумуляторе окажется уже не пя-
тёрка, а четвёрка, которая следующей ко-
мандой будет переслана по адресу (HL) -
#C001. Вот так можно легко задавать прира-
щения для регистров, регистровых пар и
байтов, адресуемых через "HL", "IX" или
"IY".
Продолжим воспоминания
Из наших предыдущих занятий у вас могло
создаться превратное впечатление, что про-
цессор Z80 выполняет свои команды последо-
вательно одну за другой без всяких прочих
вариантов.
Но это далеко не так!
Конечно, команды следуют своей чередой.
Но что управляет этим процессом?
Припомните прошлые занятия - регистр PC,
он же - программный счётчик. В нём сохра-
няется адрес той команды, которая должна
выполняться. Процессор, обрабатывая опре-
делённую команду в ячейке памяти, адресуе-
мой через PC, автоматически увеличивает
его на единицу. Таким образом, содержимое
PC постоянно модифицируется в процессе ра-
боты программы.
А если мы захотим изменить последова-
тельность выполнения команд в программе,
то нам достаточно изменить содержимое PC.
И сделать это можно при помощи манипуляций
с битами и проверки состояния бита и бай-
та, о чём в прошлый раз у нас и шла речь.
Пора применить полученные знания в деле.
Итак...
Прямой переход
Есть у процессора такая команда, как JP
(от англ. jump - прыжок, переход). За ней
следует двухбайтный параметр: адрес, на
который мы хотим сделать переход. Когда
процессор встретит команду JP, он возьмёт
следующий за ней адрес, поместит его в PC
и... перейдёт к выполнению следующей ко-
манды - той, чей адрес он только что полу-
чил.
Адрес перехода не обязательно должен на-
ходиться непосредственно в памяти следом
за JP. С не меньшим успехом им может быть
содержимое регистровых пар HL, IX, IY. Ко-
манда записывается следующим образом:
JP nn
JP cc,nn
JP (HL)
JP (ii)
- А что это за "cc" такое? - можете вы
спросить.
А это - ни что иное, как условие. Да,
команда перехода может быть не только бе-
зусловной! Вспомните таблицу из прошлого
нашего урока: была там такая колонка, как
"мнемоника условия". Вот её мы здесь и
применяем. Например:
Адрес Команда
#6000 JP C,#C003
#6003 JP (HL)
Представим себе, что в PC записано число
#6000 и процессор приступает к выполнению
команды. По ходу дела PC увеличится на три
(именно столько байт занимает команда
JP C,#C003). В процессе этого будет прове-
рено, выполняется ли условие "C". А оно
выполняется, если CY=1. После выполнения
команды Z80 помещает слово #C003 в PC и
начинает выполнять следующую команду, ко-
торая теперь уже находится по адресу
#C003.
А если условие не выполнено (CY=0)? Тог-
да процессор никаких новых данных помещать
в PC не будет, и следующая команда, кото-
рую Z80 будет выполнять, расположена по
адресу #6003. И команда эта представляет
собой всё тот же переход, но теперь ника-
ких условий проверяться не будет, в PC бу-
дет переписано содержимое "HL", туда же
будет и переход.
Упомянув условие "С", скажем и oбо всех
остальных. Вот какие мнемоники условий
можно использовать в команде "JP cc,nn":
C, NC, Z, NZ, M, P, PE, PO.
Сложного ничего в них нет. Рассмотрим их
все по порядку:
Z - ноль (флаг Z установлен)
NZ - не ноль (флаг Z сброшен)
C - перенос (флаг C установлен)
NC - нет переноса (флаг C сброшен)
M - отрицательный результат (флаг S уста-
новлен)
P - положительный результат (флаг S сбро-
шен)
PE - чётность или перепонение (установлен
флаг P/V)
PO - нет чётности/переполнения (флаг P/V
сброшен)
А теперь осталось обратить внимание на
то, что условным может быть только переход
по непосредственно указанному адресу, а
если адрес находится в регистровй паре, то
переход может быть только безусловным.
Относительный переход
Этот переход отличается от прямого тем,
что в команде задаётся не прямой адрес, а
смещение, которое процессор не записывает
в PC, а прибавляет к нему. Причём в данном
случае смещение может быть представлено
как положительным, так и отрицательным
числом (вспомните урок в "Оптроне" |21),
так что переход может быть осуществлён в
любом направлении от команды.
Записывается команда так:
JR e
JR cc,e
Мнемоника JR происходит от английского
"jump relative", что и означает "Относи-
тельный переход".
Обратите внимание на параметр команды:
"e". Он означает величину смещения относи-
тельно содержимого PC. Как видите, и эта
команда может быть условной. Правила здесь
действут аналогичные "JP", но вот набор
возможных условий несколько меньше. Прове-
ряются только C, NC, Z, NZ.
Рассмотрим механизм действия команды JR
в условном варианте:
Адрес Команда
#6000 JR NC,2
#6002 LD A,5
#6004 .......
Итак, Z80 приступает к выполнению коман-
ды по адресу #6000. Поскольку она двух-
байтная, PC будет увеличен на 2 и после
выполнения команды будет равен #6002. В
процессе выполнения команды процессор про-
веряет условие NC на истинность. Теперь,
если CY=0, то к программному счётчику бу-
дет прибавлен ещё и параметр команды JR (в
данном случае 2), операция "LD A,5" будет
пропущена, и следующей выполняемой коман-
дой будет та, что находится по адресу
#6004.
А какой вообще смысл в такой команде?
Чем она отличается от JP? Всё очень прос-
то. Ведь команда JP оперирует с прямым ад-
ресом и занимает в памяти три байта. Но
иногда переход должен быть произведён на
небольшое расстояние (как в нашем приме-
ре). Тогда нет смысла расходовать лишний
байт на полный адрес, если вполне доста-
точно диапазона +128...-127. Кроме того,
команды условного перехода могут быть по-
лезны и при написании так называемых рело-
цируемых процедур, для которых адрес раз-
мещения в памяти не имеет никакого значе-
ния (до этих процедур мы ещё доберёмся -
всему своё время).
К сему добавлю маленький вопрос: а что
будет, если в нашем примере вместо "2"
поставить "-2"?
И напоследок, как водится, о влиянии ко-
манд "JR" и "JP" на флаги. Так вот - все
эти команды абслютно никакого влияния на
флаги не оказывают!
Организация цикла
Рассмотрим случай, когда нам необходимо
организовать циклическое выполнение неко-
торого участка программы. Пусть в регистре
"B" хранится количество повторов. Итак...
LD B,5
LOOP ........
тело
цикла
........
DEC B
JR NZ,LOOP
Приведённый фрагмент может поначалу выз-
вать некоторое недоумение: "А что такое
LOOP?" Ответ прост. Дело в том, что когда
Вы пишете программу в каком-либо Ассембле-
ре, то он предоставляет для удобства такое
понятие, как "метка". Все ссылки аресуются
на неё, а не на реальный адрес, что весьма
облегчает написание и отладку программы.
Ведь слово запомнить гораздо проще, чем,
например, "#7A3E". Да и при необходимости
добавить строку-другую в уже готовую прог-
рамму вам не придётся самому пересчитывать
все адреса - это произойдёт автоматически.
Должен заметить, что такого фрагмента
программы, как этот, вы почти нигде не
встретите. Сочетание команд
DEC B: JR NZ,LOOP
почти всегда заменяют одной командой
DJNZ,
читающейся, как "уменьшить В и перейти,
если не ноль". Эта команда - двухбайтная,
и поэтому её использование даёт некоторую
экономию памяти. Опять-таки, из-за неё ре-
гистр В обычно используют для организации
счётчиков. Имеет она и недостаток: считать
можно только до 256, но это можно обойти,
использовав вложенность.
А теперь перепишем нашу программу с
учётом всего вышеизоженного:
LD B,5
LOOP ........
тело
цикла
........
DJNZ LOOP
Продолжение следует...
──═══════════──
Другие статьи номера:
|
|
Ликбез - Ассемблер взгляд издалека: Команды единичного приращения, прямой и относительный переход, организация цикла.
|
|
|
|
|
|
|
|
|
|
|