Optron
#28
08 июня 1999 |
|
Ликбез - Ассемблер взгляд издалека: Команды единичного приращения, прямой и относительный переход, организация цикла.
Ассемблер: взгляд издалека. Продолжение. Начало в ||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 Продолжение следует... ──═══════════──
Другие статьи номера:
ZX-Обоз - Обзор электронной прессы: ZX-News 47, Don News 7, Buzz 17. |
Ликбез - Ассемблер взгляд издалека: Команды единичного приращения, прямой и относительный переход, организация цикла. |
Лит. страничка - Гриф "Y-II" (Дневник - продолжение). |
Обратная связь - Пару слов об Оптроне 27. К вопросу о прикладном применении Спектрума. |
Реклама - Реклама и объявления... |
Рубрика X - О Львовском базаре. |
Четыре килобайта - 200-й юбилей А.С.Пушкина. |
Похожие статьи:
В этот день... 21 ноября