Как ориентироваться в машинном языке 1969 г.

Числа - операции и упражнения для усвоения принципов передачи данных.


  О Т К Л А Д Ы В А Н И Е  Ч И С Е Л  Н А  О Д Н О Й  Р У К Е

     ЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇЇ
         Поскольку  ЦП  "Спектрум" все построено на 8-битовых
руках  и 8-битовых ячейках памяти, очевидно, важно понять как
откладываются числа на руках. 
         В  предыдущей главе мы рассмотрели некоторые способы
передачи  информации  с  одной  руки  на  другую.  Теперь  мы
подробнее   остановимся  на  каждом  из  этих  способов.  Вы,
возможно,  помните,  что  один  из них называется регистровой
адресацией. 
         Как мы уже говорили, это просто громкое название для
простой передачи информации с одного регистра на другой. 
         Вот примеры: 

                            LD A,B
                            LD H,E
                            и т.д.

         Напомним  используемую терминологию: "LD" - означает
загрузить;  "," - означает "в" и команда в мнемоническом вмде
(сокращенном) читается как русское предложение, но с обратным
порядком  операндов.  (В  оригинале  в соответствии с нормами
английского языка говорится о прямом порядке операндов). 
         Таким  образом,  вслух  такую команду, как LD A,B мы
прочитали  бы:  "загрузить В в А". А следующий пример читался
бы:"загрузить Е в Н". 
         Мы можем передавать информацию с одной руки на любую
другую руку, как мы уже говорили. За единственным исключением
(регистр  флагов  отличается  от  всех  других регистров), вы
можете  задавать  передачу с любой руки на любую другую руку.
Допускается  даже  такая, казалось бы глупая команда, как "LD
A,A". В сокращенной записи это выглядит как "LD R,R", где R -
представляет   собой   произвольный   8-битовый  регистр,  за
исключением  F.  Теперь  мы  знаем,  что  умеем  перекидывать
информацию  с  руки на руку, но нам от этого мало проку, если
на этих руках сначала не будет какой-то информации. 
         Второй способ, которым мы можем откладывать на руках
информацию,  это  задать ЦП сколько и на какой руке отложить.
Например,  отложить  215  на  руке  "D".  Я  уверен,  что вам
достаточно  известно о мнемонике, чтобы вы могли это записать
в виде: 

                           LD D,D7
          D7 - шестнадцатеричное представление 215.

         Возможно,    вы    помните,   что   это   называется
непосредственной  адресацией.  Опять-таки вы можете проделать
это  с  любыми  регистрами  и  любыми  числами. Ограничением,
конечно,  служит размер числа, которое можно задать с помощью
8 битов: от 0 до 256. 
         Краткая  запись  такой  операции имеет вид "LD R,N",
где  R  - обозначает произвольный регистр, а N - любое число.
Здесь   по-прежнему   действует   ранее   введенное  условное
обозначение  8 битов одной буквой. Вот уже наметились сдвиги:
теперь  мы  можем  указать,  какие  числа  в  какие  регистры
загрузить,  и можем перекидывать их с руки на руку. Но мы все
еще не научились перемещать какие-либо из этих чисел в ячейки
памяти, а регистров не так много. 
         Мы   очень   кратко  показали  вам  пример  "внешней
адресации",  когда делали упражнение с вычислением разницы во
времени: 

                       LD A,(ЯЩИК N3).

         В виде общего мнемонического обозначения это даст: 

                          LD A,(NN).

         Не  забудьте,  что  в  нашей  краткой  записи скобки
означают "содержимое". 
         Обратите здесь внимание на две вещи: 
         1. так делать можно только с регистром А; 
         2.  вы  должны  задать  номер ящика в виде числа для
         двух рук (16-битового). 
         Допустима и обратная команда. Это одна из обращающих
на  себя  внимание  особенностей Z80 - в наборе команд имееся
симметрия: 

                          LD (NN),A

         Обязательно   обратите  внимание,  что  эти  команды
допустимы  только  для  регистра  А.  Есть другие команды для
других  регистров,  но  не  таких ясных, как эта. Здесь вновь
сказывается концепция доминирующей руки. 
         Давайте задержимся здесь на наносекунду и посмотрим,
что эти две команды на самом деле нам дают. 
         Во-первых,   диапазон   значений  чисел,  задаваемых
числом для двух рук (NN), будет от 0 до 65 535. Это 64К, т.е.
с  помощью  этой  команды можно получить доступ не более, чем
64К  памяти.  Это  значит,  что  вся  память (ПЗУ, программа,
дисплей,  свободная  память)  должна  уместиться в 64К. В 16К
"Спектрум" на самом деле 16К используются ПЗУ и 16К - памятью
с  произвольным  доступом,  что  вместе  составляет  32К. 16К
относится  только  к  памяти  с  произвольным доступом. В 48К
"Спектрум"  имеются  те  же  самые  16К ПЗУ плюс 48К памяти с
произвольным доступом, что вместе составляет 64К. Поэтому для
Z80  невозможно получить доступ к большему количеству памяти,
чем 48К"Спектрум". 
         Команда   LD   A,(NN),   читаемая   как   "загрузить
содержимое  ячейки  NN  в A", очень богата возможностями. Она
позволяет  нам читать содержимое любой ячейки памяти, будь то
ПЗУ,   или   память   с   произвольным  доступом.  Вы  можете
использовать  эту  команду  для  исследований по вашему вкусу
даже   для  тех  ячеек,  где  память  отсутствует.  Например,
попытаться посмотреть, что находится за пределами 32К памяти,
даже если у вас нет дополнительной памяти. Вас ждет сюрприз -
там вовсе не везде нули. 
         Обратная  команда  "LD (NN),A", которая читается как
"загрузить А в ячейку памяти NN", будет пытаться вести запись
так  же  в  любую  ячейку  памяти,  но  для  нее  сказываются
физические  ограничения.  Вы не можете вести запись в ячейки,
которые   не   могут   содержать   эту   информацию,  подобно
несуществующей памяти за пределами размера вашей системы. 
         Одно   из   свойственных  этой  команде  ограничений
состоит   в  том,  что  вам  необходимо  во  время  написания
программы  знать,  какую ячейку памяти мы хотим проверять или
записать  в  нее.  Сокращение NN означает определенное число,
например, 17 100, а не переменную. 
         Вы  не можете использовать эту команду в эквиваленте
циклу  "FOR  _  NEXT"  на  машинном  языке.  Поэтому основное
применение  этой  команды - отведение конкретных ячеек памяти
под хранение переменных. Например, задание 

                   32000 = скорость
                   32001 = высота
                   32002 = остаток горючего

в программе типа посадки на луну. 
         Поэтому  вы  могли  бы  запроектировать программу, в
которой  вы  брали количество оставшегося горючего, уменьшали
его и запоминали бы новое количество горючего опять в этой же
ячейке.  В  момент  написания программы вы будете знать адрес
той   ячейки   памяти,   которая  послужит  вместилищем  этой
информации. (В оригинале:STROEHOUSE - это слово отсутствует в
двухтомном англо- русском словаре, возможно, опечатка). 
         Давайте уточним этот момент. Ячейка - не переменная.
Это просто ячейка памяти, которую вы используете для хранения
информации.  Поэтому  при  написании своей программы на языке
ассемблера  вы напишите что-нибудь вроде LD A,(FUEL). И когда
вы  сами  или программа ассемблера начнет задавать конкретный
текст  машинной  программы  для  этой  команды,  вы  замените
"горючее"  шестнадцатеричным адресом ячейки памяти, указанной
вами. 
         Но что, если мы не знаем точный адрес ячейки памяти,
где мы должны искать информацию? Предположим, мы можем только
посчитать,  где  эта  информация должна находиться. Поскольку
нам  необходимо  16  битов,  чтобы  задать адрес произвольной
ячейки   памяти,  нам  придеться  хранить  его  в  16-битовом
регистре,  т.е. в одной из пар регистров BC, DE или HL, или в
одном  из индексных регистров IX или IY. Один из способов для
этого   -  сделать  так,  чтобы  в  одной  из  пар  регистров
содержался   адрес   ячейки   памяти.   Поскольку  информация
содержится  в регистре и нам не дан адрес непосредственно, мы
называем    эту   форму   адресации   косвенной   регистровой
адресацией. 
         Мнемоническое  сокращение  для  таких  команд  имеет
вид: 

                          LD R,(HL)
                          LD A,(BC)
                          LD A,(DE)

По русски эти команды читаются так:
"загрузить  в  регистр  содержимое  ячейки памяти, на которую
указывает HL; 
"загрузить в А содержимое ячейки памяти, на которую указывает
ВС; 
"загрузить в А содержимое ячейки памяти, на которую указывает
DE. 
         Обратите  внимание  ,  что,  используя HL в качестве
указателя на нашу ячейку памяти, мы можем провести загрузку в
любой  регистр, даже в Н или L, хотя это и звучит странно, но
что   так   происходит   потому,   что   пара   регистров  HL
привилегирована точно так же, как привилегирован регистр А. И
здесь также имеется симметрия по отношению к этим командам, и
мы  можем  аналогичным образом загружать информацию в ячейкии
памяти: 

                          LD (HL),R
                          LD (BC),A
                          LD (DE),A

         Это    также   называется   "косвенной   регистровой
адресацией"  вне  зависимости  от  того,  в каком направлении
перемещается информация. 
         С  другой  стороны,  мы могли бы применить индексные
регистры IX и IY для указания ячейки памяти. 
         Краткая запись этих команд имеет вид: 

                        LD R,(IX + Д)
                        LD R,(IY + Д),

где   R   -  опять  произвольный  регистр,  а  Д  -  смещение
относительно  адреса,  на  который  указывает  IX  или IY (не
спутайте  обозначения:  "Д" - мы имеем в виду не регистр D, а
"Д" - смещение (DISPLACEMENT)). 
         Число  "Д" для одной руки (8-битовое число), которое
нужно  указывать  во  время программирования и нельзя сделать
переменным.  В этом слабость данной конкретной команды. И это
означает,  что  ее применение обычно ограничивается чтением и
записью таблиц, содержащих данные. Имеется также симметричная
команда 

                        LD (IX + Д),R
                        LD (IY + Д),R

         Если   этот  конкретный  способ  адресации  выглядит
несколько  усложненным,  не  беспокойтесь,  вам  он  вряд  ли
понадобится  в  нескольких первых ваших программах. Чип Z80 в
ЭВМ   "Синклер"   в  высшей  степени  универсален  вы  можете
комбинировать  разные  способы загрузки чисел, описанных нами
выше.  Например,  вы  можете  комбинировать  непосредственную
адресацию (т.е. задание числа, которое вы хотите загрузить) с
внешней  адресацией  (т.е.  задание адреса загрузки с помощью
пары  регистров).  Это  называется  НЕПОСРЕДСТВЕННОЙ  ВНЕШНЕЙ
АДРЕСАЦИЕЙ. 
         К  сожалению,  вы  можете  использовать  только пару
регистров  HL  и  поэтому  сокращенная  запись имеетт вид: LD
(HL),N.  Это  удобно,  поскольку  вы  можете  непосредственно
заполнить  ячейку  памяти без необходимости сначала загрузить
это значение в регистр. 
         Возможна    аналогичная   комбинация   с   индекными
регистрами.   Она   называется   НЕПОСРЕДСТВЕННАЯ   ИНДЕКСНАЯ
АДРЕСАЦИЯ.  Эта  команда  используется  более  ограниченно  и
сокращенная форма таких команд имеет вид: 

                        LD (IX + Д),N
                        LD (IY + Д),N

     ПРИМЕНЕНИЕ ЭТИХ КОМАНД В ПРОГРАММЕ НА МАШИННОМ ЯЗЫКЕ

         Давайте попробуем на практике применить некоторые из
этих команд "LD". 
         Из  предыдущих глав нам известно, что после возврата
из  USR  в  программе  на  машинном  языке значение USR равно
содержимому   ВС.   Давайте   выполним  следующую  программу:
(сначала  загрузите  и  запустите  редактор машинного языка в
коде EZ и задайте адрес загрузки 32000): 

                           1 0E  00
                           2 C9

         Теперь  с помощью команды DUMP запишите этот текст в
память.  В  дальнейшем мы уже не будем давать вам такие явные
указания по загрузке и выполнению программ на машинном языке,
поскольку  такой  метод  трудоемок  и  не  дает  вам никакого
дополнительного понимания сути программы. 
         Мы  будем  предполагать, что к настоящему моменту вы
достаточно  знакомы  с  написанным  на  "Бейсике"  редактором
машинного  языка  в  коде EZ и с помощью таблиц в конце книги
сможете ввести программу. Поэтому все наши программы мы будем
приводить в следующем виде: 

                   0E 00     LD C,0
                   C9        RET

         В  этих  обозначениях  текст  программы  на машинном
языке   приводится   слева,   а   мнемонические   обозначения
ассемблера  -  в  колонке  справа.  В  них  также  очень ясно
показано,  для каких команд требуется всего 1 байт (такие как
RETURN), каких - 2 байта и т.д. Напомним, что в Z80 некоторые
команды могут занимать до 4 байтов. 
         Еще  одна  проблема состоит в том , что мы попробуем
сделать  все наши программы независимыми от начального адреса
(где  начинается  программа  в  памяти).  Так  что  не  имеет
значения что вы укажете в качестве адреса начальной загрузки.
Тем  не  менее  помните,  что  эти  программы можно вводить с
помощью  программы  "Редактор  машинного  языка  в  коде EZ",
помещенной   в   конце  книги,  или  любой  другой  программы
загрузки, которую вы сами можете разработать. 
         Какого  результата  вы  ожидаете  до выполнения этой
программы на машинном языке (вы должны ввести текст программы
в память и затем применить команду RUN в программе кода EZ)? 
         Программа  устанавливает  регистр С в паре регистров
ВС  равным  нулю.  А  вы  знаете,  что ВС начинается с адреса
программы, равного 32000. 
         Пусть предлагаемый ответ будет: 

                   A. 0000
                   B. 32000
                   C. 31896

         Теперь выполните программу. Совпадет ли ответ с тем,
что  вы  предполагали? Если вам неясно почему получился такой
ответ, вернитесь и перечитайте главу "как считает ЭВМ". 
         Теперь попытайтесь выполнить следующую программу: 

                   06  00      LD B,0
                   0E  00      LD C,0
                   C9          RET

это даст вам ожидаемый результат 0 при ВС=0 (оба регистра В и
С установлены равными 0). 

                          УПРАЖНЕНИЕ

         Вам  может доставить удовольствие попробовать решить
несколько  занимательных задач, таких, как загрузить какое-то
число в А, переместить его в L, установить Н равным 0 и т.п. 

                          УПРАЖНЕНИЕ

         Файл  атрибутов  начинается с адреса 5800Н. Мы можем
установить  HL  так,  чтобы  указывать  на  файл  атрибутов с
помощью следующей программы: 

                       26  58    LD H,58H
                       2E  00    LD L,0

         Это  означает,  что вы можете теперь менять цвета на
дисплее с помощью команды LD (HL),N. 
         Структура  файла  атрибутов описана в руководстве по
"Спектрум".  Давайте  установим  первую  литеру  так:  бумага
красная, чернила белые, режим мигания включен. 

                    1 0 1 1 1 0 1 0 = ВАН

так что следующая строка программы будет такая: 

                    36  ВА    LD (HL),BAH

         Далее,  вы  никогда  не должны забывать вернуться из
программы на машинном языке, так что последней строкой должна
быть 

                        С9        RET

         Выполните эту машинную программу. Работает ли она? 

                    ФЛАГИ И ИХ ПРИМЕНЕНИЕ

         Флаги  -  это  такие  красивые  флажки,  которыми вы
размахиваете на государственных праздниках......-Вовсе нет! 
         В  машинном  языке "флаг" означает "отметка". Флаг -
это  то,  что вы поднимаете, если хотите пометить для кого-то
другого,   что   выполнено   определенное  условие.  Очевидна
аналогия  с мореплаванием, где флаги поднимают в знак траура,
для   обозначения   страны,   пиратского   корабля   или  еще
чего-нибудь. 
         Причина,   по   которой   конструкторы  Z80  (как  и
большинство   конструкторов  ЦП)  используют  флаги  в  своих
машинных  языках  в том, чтобы дать программисту информацию о
числе,  находящемся  на  доминирующей руке ЦП (в регистре А),
или информацию о только что выполненном последнем вычислении.
Напомним,  что  один  из  регистров ЦП отведен под флаги. Это
регистр  F.  Вы  могли  также  обратить внимание на то, что в
начале  последней  главы в таблице сведены различные команды,
которые  должны  были  в  этой  главе  рассматриваться. Часть
таблицы  была отведена на описание воздействия каждой команды
на  флаги.  К счастью, ни одна из команд этой последней главы
не  влияла  ни на один флаг. Легче всего понять функции флага
нуля.   Этот   флаг   будет  подниматься  на  флагшток,  если
содержимое  регистра А равно нулю. Есть много важных решений,
которые   будут   зависеть  от  равенства  А  нулю.  Обратите
внимание,  что флаг нуля либо установлен, либо сброшен. Вы не
можете  получить  промежуточный  результат (в стиле "немножко
беременна".  Так  что  вам  понадобится  всего  один  бит для
определения  флага  нуля.  То  же  самое  относится  ко  всем
остальным   флагам.  Они  либо  установлены,либо  сброшены  и
требуют всего одного бита. 

                      ДРУГИЕ ТИПЫ ФЛАГОВ

         Регистр  F  - обычный 8-битовый регистр, и поэтому в
нем можно разместить 8 различных флагов. На практике, однако,
конструкторы придумали всего 6 флагов. 

   S      Z         H            P/V          N         C

   !      !         !             !           !         !
   !      !         !             !           !         !
1.SIGN 2.ZERO 3.HALF-CARRY 4.PARITY FLAG 6.SUBTRACT 7.CARRY
  FLAG   FLAG   FLAG       5.OVER FLAG     FLAG       FLAG

 1 - флаг знака; 
 2 -флаг нуля; 
 3 - флаг половинного переноса; 
 4 - флаг четности; 
 5 - флаг переполнения; 
 6 - флаг вычитания; 
 7 - флаг переноса 
         На  самом  деле  разработчики придумали 7 флагов, но
решили,  что  одним  регистром можно реализовать два флага: и
четности, и переполнения. 
         Давайте  теперь  подробнее рассмотрим каждый из этих
флагов. 

                          ФЛАГ НУЛЯ

         Этот  флаг мы уже рассматривали выше. Его прикладное
значение    очевидно.   Он   обычно   устанавливается   после
арифметических   операций,   поскольку  служит  для  описания
содержимого  регистра А. Обратите, однако, особое внимание на
то,  что  в  регистре  А  может  содержаться  0,  а флаг нуля
установлен не будет. Так легко может случиться при выполнении
команды  LD  A,0. Мы выще уже говорили, что ни одна из команд
загрузки  для  одной  руки  (8-битовая) не оказывает никакого
влияния  ни на один из флагов. Флаг нуля не будет установлен,
а в А будет нуль. 
         Флаг   нуля   также  устанавливается,  если  нулевым
оказывается   результат   команд  из  группы  "перемещений  в
круговом порядке и сдвигов". 
         Кроме   того,  флаг  нуля  оказывается  единственным
зримым  результатом  некоторых  команд  проверки,  таких  как
группа  команд  "проверка  бита".  В  этих  случаях флаг нуля
устанавливается, если проверяемый бит равен нулю. 

                          ФЛАГ ЗНАКА

         Флаг знака очень напоминает флаг нуля и действует по
преимуществу  на  том  же  самом наборе команд (расхождение в
основном   касается   группы  "проверки  бита",  где  понятие
отрицательного бита при любой интерпретации лишено смысла). 

                        ФЛАГ ПЕРЕНОСА

         Это  один  из  наиболее  важных  флагов, имеющихся в
языке    ассемблера,    поскольку    без    него   результаты
арифметических  действий  в  ассемблере  были  бы  совершенно
бессмысленными.  Нужно  помнить, что команды языка ассемблера
всегда  относятся  либо  к числам для одной руки (8-битовым),
либо  к  числам  для двух рук (16-битовым). Это означает, что
числа, с которыми мы имеем дело, могут быть либо 

                      8-BIT  **)   0-255
                     16-BIT  **)   0-65535,
либо, если вы включаете перенос 
                      8-BIT  **)   0-256
                     16-BIT  **)   0-65536.

Рассмотрим   ситуацию,   в  которой  мы  выполняем  следующее
вычитание 

                   2 0 0
                -
                   2 0 1
                   -----
      результат =  2 5 5    !!! 

         Это  прямое следствие того, что у нас имеется только
ограниченный  диапазон  чисел, и то же самое может произойти,
очевидно, и с 16-битовыми числами. 
         Мы  уже  видели, что на одной руке вы можете считать
только  до 255. Что произойдет, если регистр уже содержит 255
и  вы добавляете 1? Возможно вам понравится представлять себе
регистр  работающим так же, как спидометр в вашем автомобиле.
После того, как вы достигли максимума, он "проворачивается" и
снова  начинает отсчет от нуля. Точно так же, если в регистре
или на спидометре автомобиля все нули, и вы поворачиваете его
назад,  вам высветится наивысшее значение, или для 8-битового
регистра  - 255. Именно поэтому результат 200 - 201 дает 255.
Если  бы  мы были торговцами машинами, мы, очевидно, захотели
бы  иметь  какой-то знак, что спидометр прокрутился вперед (в
этом  случае автомобиль прошел больше, чем кажется) или назад
(в   этом   случае  его  показания  подделаны).  Такого  типа
указатели имеются при программировании на машинном языке и их
называют   флагами   переноса.   К  счастью,  нам  нет  нужды
беспокоиться о подделке значения регистра. 
         Мы видели, что флаг переноса может быть установлен в
результате  вычитания  при  наличии  "ухода  за  нуль".  Флаг
переноса  может  быть  также установлен в результате операций
сложения,  если  должно  быть  переполнение.  Поэтому  удобно
представлять себе бит переноса как 9-й бит регистра А: 

          NUMBER     CARRY BIT    NUMBER IN BIT FROM
           132           -         1 0 0 0  0 1 0 0
         + 135           -         1 0 0 0  0 1 1 1
          -----                   ------------------
           267           1         0 0 0 0  1 0 1 1

NUMBER  - число; CARRY BIT - бит переноса; NUMBER IN BIT FROM
- число в виде битов. 
         Однако,  поскольку у нас нет 9 битов, а в регистре А
будет содержаться число 0ВН (десятичное - 11) и перенос будет
установлен  (т.е. равен 1). Можно заметить, что при вычитании
занимание из 9 бита также приведет к появлению в нем 1. 
         Использование  флагов  в  конструкции  на  машинноми
языке, экви- валентной предложению "IF....THEN......". 
         В    языке   "Бейсик"   у   нас   есть   возможность
конструировать ситуацию типа "IF.....THEN...", такие как 

                       IF A=0 THEN....
           1. WHERE WHAT FOOLLOWS CAN BE "LET...."
                               2  OR "GOTO..."
                               2  OR "GOSUB.."

             1 -где-то, что следует, мохет быть; 2 - или.
         Принятие   решения   точно   такого  же  типа  можно
запрограммировать   на   машинном   языке   (за   исключением
предложения LET....). 
         Вместо  того,  чтобы  написать  "IF  A=0", мы просто
проверяем  флаг  нуля:  если  он установлен, то мы знаем, что
А=0. 
         Три  рассмотренных нами к настоящему моменту флага -
это  в  основном  все, что нам нужно, чтобы выбрать следующую
команду   для  выполнения.Подобная  команда  имеет  следующий
формат: 

                          JP CC,END,

где JP -мнемоническое обозначение колманды перехода (JUMP), а
END - удобная метка. 
         Эта  команда  по  русски  читается  как "перейти при
условии СС на END". 
      Условие СС может быть любым из следующих: 
                   Z   (= нуль)
                  NZ   (= не нуль)
                   P   (= положительное)
                   M   (= минус)
                   C   (= перенос установлен)
                  NC   (= нет переноса)

                  ФЛАГ ЧЕТНОСТИ/ПЕРЕПОЛНЕНИЯ

         Этот  флаг  для  некоторых команд действует как флаг
четности,  а  для  других  -  как  флаг переполнения. Однако,
путаница  возникает  редко,  поскольку  эти  два  типа команд
обычно не встречаются вместе. 
         Роль  флага,  как  указателя  четности - выступает в
логических  операциях. Он устанавливается в том случае , если
в  результате  установленным  оказывается  четное  количество
битов.  Более  подробно  этот  вопрос  мы  рассмотрим в главе
логических операций. 
         Переполнение  говорит  вам  о  том,  что  только что
выполненная   вами   арифметическая   операция   может   дать
результат,  не  умещающийся  в 8 битов. Вместо того, чтобы на
самом  деле  означать,  что для записи результата понадобился
9-й  бит,  этот флаг говорит о том, что в результате операции
8-ой бит изменился. 
         В  приведенном выше примере до сложения 132 и135 8-й
бит  был  равен  1,  а  после  -  0.  Так что должен был быть
установлен флаг переполмемия, но флаг переполнени будет также
установлен и в результате такого сложения: 

                 64         0 1 0 0  0 0 0 0
               + 65         0 1 0 0  0 0 0 1
                ----        ----------------
                129         1 0 0 0  0 0 0 1

                       ФЛАГ  ВЫЧИТАНИЯ

         Этот  флаг устанавливается, если последней операцией
было вычитание. 

                  ФЛАГ ПОЛОВИННОГО ПЕРЕНОСА

         Этот   флаг  устанавливается  способом,  аналогичным
флагу  переноса,  но  только  в  том  случае,  когда  имеется
переполнение  или  занимание  из 5-го бита, а не из 9-го. Как
флаг  вычитания,  так и флаг половинного переноса применяются
только    для   арифметических   операций   над   двоично   -
кодированными  десятичными числами. Мы рассмотрим эти флаги в
главе   "Арифметические  действия  над  двоично-кодированными
десятичными числами". 

                         В Ы В О Д Ы

         Флаги   применяются  ЦП  для  указания  определенных
условий  после выполнения команд. Имеется шесть таких флагов,
о  каждом  из  которых  можно говорить, что он установлен или
сброшен.  Представляющие эти флаги биты - это шесть из восьми
битов регистра F. Два остальных бита не используются. 
         Различными флагами отмечаются следующие ситуации. 
                 - перенос
                 - нуль
                 - четность или переполнение
                 - знак
                 - отрицание
                 - половинный перенос 
         Не все команды оказывают влияние на все флаги сразу.
Некоторые  влияют  на  все  флаги,  а  некоторые  - только на
конкретные. Другие же вовсе не оказывают на них действия. 

     УВЕЛИЧЕНИЕ И УМЕНЬШЕНИЕ ЧИСЕЛ НА ОДНОЙ И ДВУХ РУКАХ

         В  последней главе мы рассмотрели понятие флага, а в
предшествующей  ей  выяснили,  как  ЦП  может загружать любые
нужные числа на свои руки и ноги. 
         Давайте    теперь   рассмотрим   простейший   способ
манипулирования  числами на пальцах: мы можем увеличивать или
уменьшать  представленные  числа. Это достаточно элементарные
арифметические  действия. Но это все-таки сложнее, чем просто
откладывать  конкретные числа на пальцах. Действие увеличения
по  существу  сводится  к увеличению на единицу любого числа,
отложенного  на  пальцах.  Это  действие можно использовать в
таких   обычных   ситуациях,   как   перепись  населения  или
управление движением на некотором перекрестке. 

                          УВЕЛИЧЕНИЕ

         У   Z80   имеется   возможность   увеличить   число,
отложенное  на  пальцах любой одинарной руки, имеющейся у ЦП.
Именно это подразумевается общим мнемоническим обозначением: 

                            INC R

INC = INCREASE (увеличить) говорит само за себя. 
         Можно  также  увеличить  число, находящееся на любой
ноге  (включая пары регистров,которые на самом деле ногами не
являются).  Это  увеличение  числа  на наших ногах записывают
так: 

                            INC RR
                            INC IX
                            INC IY,

где  RR  обозначает  пару  регистров,  такую  как ВС, DE, HL.
Обратите еще раз внимание на простой способ обозначения того,
какие   операции   используют  8-битовые  числа,  а  какие  -
16-битовые. 
         8-битовые числа обозначаются одной буквой, А 

         ---------                    -----
         16-битовые - двумя
         ----------   -----

         Однако  команда "увеличение" на самом деле имеет еще
большие возможности, чем видно из приведенных примеров. Можно
увеличить  содержимое  любой  ячейки  памяти,  если мы сможем
задать   ее   адрес   с   помощью   индексных  регистров  или
привилегированной пары регистров, HL: 

                         INC (IX + Д)
                         INC (IY + Д)
                         INC (HL)б

       где Д - смещение (DISPLACEMENT), а не регистр D.

                       ВАЖНОЕ ЗАМЕЧАНИЕ

         Вспомним   поточнее,   как  мы  условились  понимать
употребление скобок: 
         скобки - означают - содержимое. 
         Это  очень  важно,  поскольку  есть большое сходство
между командами: 

                            INC HL
                            INC (HL)

но при выполнении они очень сильно различаются. 
         Первая читается как "увеличить HL", тогда как вторая
-  "увеличить  содержимое  ячейки,  адресом  которой является
HL". 
Этот  второй  способ  чтения  часто сокращается до "увеличить
содержимое HL". 
         Если   только   вы   помните  правила  мнемонических
сокращений,   вы   избежите  путаницы  такого  рода.  Давайте
посмотрим,   как   работает   каждая   из   этих   команд   в
предположении, что HL=5800H. 

INC  HL  проверить HL. Увеличить на единицу отложенное на его
         пальцах число. Результат HL = 5800Н. 
INC  (HL)  проверить  HL.  Найти  ячейку  памяти,  на которую
         ссылается  это  число. Увеличить число в этой ячейке
         на единицу. Результат: HL = 5800H 
                          (5800H)  =   (5800H)+1 

         У  этих  операций  есть  существенные  различия.  Вы
можете  захотеть  выполнить  обе версии, - 5800Н - это начало
файла атрибутов. Обратите также ваше внимание на то, что "INC
HL"  -  команда,  действующая  на 16-битовое число, тогда как
"INC (HL)" - команда, действующая только на 8-битовое число -
на число, хранимое в ячейке 5800H. 

                       УМЕНЬШЕНИЕ ЧИСЛА

         Симметричность  набора  команд  Z80  почти наверняка
должна  обеспечивать,  чтобы все, что вы можете уменьшить, вы
могли также и увеличить. И именно так обстоит дело. 

                   DEC R
                   DEC RR
                   DEC IX
                   DEC IY
                   DEC (HL)
                   DEC (IX + Д)
                   DEC (IY + Д)

Мнемоническое   сокращение  DEC  по  английски  читается  как
"DECREASE" (уменьшить), и здесь нужно тоже быть внимательными
при использовании скобок. 

                       ВЛИЯНИЕ НА ФЛАГИ

         Поскольку  команды уменьшения и увеличения 8-битовых
чисел   воздействуют  на  все  флаги,  за  исключением  флага
переноса, именно здесь удобно дать обзор работы с флагами. 
   Важное  замечание:  команды увеличения и
                     уменьшения  для  16-бито-  вых  чисел не
                     влияют  на  какие  бы  то ни было флаги.
                     Изменяют  флаги  только  операции увели-
                     чения и уменьшения для 8-битовых чисел. 
   Флаг знака:       этот флаг будет установлен в
                     (=1),  если  бит 7 8-битового результата
                     равен   1.   В   соответствии   с  нашей
                     предшествующей  аналогией  это  означает
                     что  он  будет  установлен,  если поднят
                     большой  палец.  Обратите  внимание, что
                     это  произойдет вне зависимости от того,
                     какой   способ   пред-  ставления  чисел
                     используется. 
   Флаг нуля:        этот флаг будет установлен (=1), 
                     если 8-бито- вый результат равен нулю. 
   Флаг переполнения:этот флаг будет установлен (=1), если 
                     содержимое   бита   7  8-битового  числа
                     изменяется в результате операции. 
   Флаг половинного
   переноса:         этот флаг будет установлен (=1), если 
                     имеется  перенос  или  занимание из 4-го
                     бита 8-битового числа. 
   Флаг  отрицания:  этот  флаг  устанавливается,  если
последней   выполненной  командой  было  вычитание.  Так,  он
сбрасывается (=0) для INC и устанавливается (=1) для DEC. 

                   ПРЕДЛАГАЕМЫЕ УПРАЖНЕНИЯ

         С  помощью группы команд LD, INC и DEC сделайте так,
чтобы  в  результате  операции  URS  возвращались  нужные вам
числа. Это позволит вам освоиться с этими командами. 

                         В Ы В О Д Ы

         Мы  можем  увеличивать  или  уменьшать  содержимое в
любом  из  8-битовых  регистров,  в  любой  из 16-битовых пар
регистров или в любом из 16-битовых индексных регистров. 
         Мы  можем также увеличивать или уменьшать содержимое
ячеек  памяти,  адреса  которых заданы парой регистров HL или
индексными регистрами. 
         Увеличение   или   уменьшение  16-битовых  чисел  не
оказывает влияния ни на один из флагов. 
         Увеличение  или  уменьшение  8-битовых  чисел  как в
регистрах,   так   и  в  памяти,  влияет  на  все  флаги,  за
исключением флага переноса. 





СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Презентация - Презентация новых журналов: Oberon 2, Spectrofon 21.
Cенсация - AloneCoder декомпилировал Pro Tracker 3.x
B.B.S. Новости - Открылась новая станция SHADOW BBS.
Конкурс - еще раз о конкурсе прошлого номера.
Реклама - Самый широкий выбор программного обеспечения для "ZХ-Sрectrum"!

В этот день...   25 апреля