Micro #21
08 июля 1999

Учебник - Программирование в машинных кодах и на языке АССЕМБЛЕРА (часть первая).

          <<  И Н Ф О Р К О М >>


         ПЕРСОНАЛЬНЫЙ  КОМПЬЮТЕР
              "ZX-SPECTRUM"

    Программирование в машинных кодах
          и на языке АССЕМБЛЕРА

               Москва 1993




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


                ОТ АВТОРОВ

  Книга,  которую  Вы держите в руках, уже
получила  широкую  известность,  как самый
доступный  самоучитель  для тех, кто хочет
преодолеть психологический барьер и перей-
ти  от программирования на БЕЙСИКе к прог-
раммированию  в  машинном  коде или просто
хочет   понимать  машинный  код  фирменных
программ. Первое издание этой книги мы вы-
пустили  два  года  назад,  в 1990 году, и
сейчас  в стране уже есть тысячи любителей
бытовых   персональных   компьютеров  типа
ZX_Spectrum (система "Синклер"), самостоя-
тельно  освоивших тонкости машинного прог-
раммирования по этой книге. Первое издание
было  выпущено в трех томах. Сейчас мы об-
ъединили  все три тома (учебник, практикум
и  справочник) в рамках единой книги, нес-
колько   подкорректировали  и  значительно
(примерно  на  20%)  дополнили содержание.
Основным дополнением стали разделы, посвя-
щенные  описанию  системы прерываний комп-
ьтера,  разбору  концепции потоков и кана-
лов,  понятию  о  директивах  АССЕМБЛЕРа и
вопросам, связанным со стандартизацией ру-
сификации  компьютеров. Как показал первый
опыт,  именно эти вопросы нуждались в уси-
ленном освещении.
  "ИНФОРКОМ"  продолжает работу над книга-
ми,  посвященными компьютерам "Спектрум" и
совместимым с ними. В настоящий момент на-
чат выпуск многотомного издания, посвящен-
ного  работе  с графикой "Спектрума". Нес-
мотря  на то, что каждый из этих томов яв-
ляется  самостоятельной учебной единицей и
может  быть использован независимо от про-
чих,  тем не менее, их можно считать логи-
ческим  продолжением  данного  издания уже
хотя  бы потому, что "Первые шаги в машин-
ном  коде Z-80" в силу естественных причин
стали базовой книгой для наших последующих
разработок. "ИНФОРКОМ" благодарит всех чи-
тателей  первого  издания, приславших свои
отзывы,  пожелания  и рекомендации и особо
выражает персональную признательность сво-
им  корреспондентам Баянову К.Н. за подго-
товку  разделов  I.5.18, II.4.4.7, III.5 и
Пашорину   В.И.   за   подготовку  раздела
II.5.5.
                               "ИНФОРКОМ".
                      Москва, август 1992.


                 ВВЕДЕНИЕ

  Проведенное в начале 1990 года анкетиро-
вание  наших заказчиков показало их глубо-
кую заинтересованность в освоении програм-
мирования   в  машинных  кодах  для  Синк-
лер-совместимых  компьютеров, получивших в
нашей  стране  наибольшее  распространение
среди ПЭВМ бытового класса.
  Процессор Z-80, на базе которого собраны
компьютеры  этой системы, приобрел широкую
популярность  в  мире благодаря своей уни-
версальности, наличию обширной системы ко-
манд и технологичности производства, обес-
печившей  ему  большие  объемы выпуска при
сравнительно невысокой цене.
  Этот  процессор  применяется не только в
многочисленных   компьютерах,  входящих  в
систему "Синклер-Спектрум", но и в компью-
терах  других систем. Среди них компьютеры
семейства  MSX  ("ЯМАХА",  "СПЕКТРОВИДЕО",
"ТОШИБА",  "ПАНАСОНИК"  и др.), компьютеры
систем  "ЭНТЕРПРАЙЗ", "ШАРП", многие комп-
ьютеры  фирмы  "АМСТРАД" и пр. В принципе,
материалы этой книги могут быть на 90% ис-
пользованы  и теми, кто работает с компью-
терами этих систем. В настоящее время про-
цессор  Z-80 очень хорошо документирован в
мировой литературе. Наиболее фундаменталь-
ными   трудами  для  программистов  любого
уровня являются монографии Лэнса Левенталя
(LANCE  A.LEWENTHAL)  "Программирование на
Ассемблере  Z-80" ("Z-80 ASSEMBLY PROGRAM-
MING"),  а  также "Процедуры на Ассемблере
для  процессора Z-80" ("Z-80 ASSEMBLY LAN-
GUAGE SUBROUTINES).
  Эти  очень  хорошие  книги, к сожалению,
весьма  объемны (по 500-600 стр.) и не пе-
реведены  на русский язык, что делает сом-
нительной  возможность  их  широкого расп-
ространения у нас в ближайшие годы.
  Многочисленные  прочие  книги зарубежных
авторов,  посвященные программированию для
Синклер-совместимых компьютеров в машинном
коде,  имеют  в  качестве недостатков либо
недостаточную  систематичность  изложения,
либо повышенную инструктивность подачи ма-
териала.  В  первом случае они оказываются
неплохим подручным справочником, а во вто-
ром  - неплохим учебником, но для тех, кто
уже  в  принципе подготовлен. Учебником же
для  тех, кто самостоятельно начинает раз-
бираться  с  самого начала, они могут слу-
жить очень ограниченно.
  В  своей книге, предлагаемой Вашему вни-
манию,  мы  постарались, как сумели, соче-
тать  популярность,  систематичность и ин-
формативность изложения. Те, кто не нужда-
ются  в элементарном освоении программиро-
вания  в машинных кодах, могут сразу обра-
титься  ко  второй  части  "Практикум...".
Чтобы  не дублировать справочный материал,
который  необходим как тем, кто работает с
первой  частью, так и тем, кто работает со
второй,  мы вынесли его отдельно, в третью
часть.
  Мы очень рекомендуем сопровождать чтение
этой книги самостоятельным просмотром кода
фирменных  программ  с  помощью какой-либо
дисассемблирующей  программы, например MO-
NITOR 16/48, MONS 3, ULTIMON и т.п.
  Мы должны также порекомендовать Вам наше
периодическое  издание  "ZX-РЕВЮ".  На его
страницах  Вы сможете найти почти все, что
Вам  может потребоваться из программного и
информационного   обеспечения  компьютеров
системы  "Синклер"  и кое-что, связанное с
аппаратными вопросами.
  У нас возможно приобретение полных годо-
вых комплектов "ZX-РЕВЮ" за 1991 и за 1992
год,  выполненных  в виде отдельной книги.
Выходят  и  выпуски 1993 года. Для справки
укажем,  что объем одного полного годового
комплекта  "ZX-РЕВЮ" примерно в 5 раз пре-
восходит объем данной книги.
  Свои  пожелания, замечания и предложения
Вы  можете направить нам по адресу 121019,
Москва,  Г-19,  а/я  16. Вы всегда сможете
выбрать  из списка выпущенной нами литера-
туры то, что Вам будет по душе.


     I. ПЕРВЫЕ ШАГИ В МАШИННЫХ КОДАХ


      1. САМЫЙ - САМЫЙ ПЕРВЫЙ ШАГ...

  Многие  любители не испытывают серьезных
трудностей в овладении БЕЙСИКом. Для этого
достаточно  сравнительно немного практики.
Но  рано или поздно они приходят к барьеру
"машинного  кода". Как это ни печально, но
некоторые так перед ним и останавливаются.
Это ни в коей мере не связано с отсутстви-
ем желания или способностей, просто многие
не  знают,  с  чего начать. Если в БЕЙСИКе
можно  начинать  с чего угодно (при ошибке
компьютер  сам  Вас поправит), то здесь Вы
оказываетесь  с процесором один на один, и
такой  метод проб и ошибок не срабатывает.
Одним  словом,  есть некий психологический
барьер, который бывает трудно преодолеть в
одиночку.  Известно,  что  для того, чтобы
научиться  программировать,  надо  взять и
начать программировать. "ИНФОРКОМ" предла-
гает  Вам следующий компромиссный подход -
сначала в рамках этой главы мы, беря "быка
за рога", просто начнем программировать, а
затем посвятим оставшуюся часть книги сис-
тематическому  изложению  материала. Итак,
давайте  напишем первую программу в машин-
ном  коде.  Прежде  всего, выделим для нее
область  памяти. Если Вы читали нашу книгу
"Большие  возможности  Вашего "Спектрума",
то  знаете,  что для БЕЙСИКа в оперативной
памяти компьютера отведена область памяти,
начинающаяся с адреса, на который указыва-
ет  системная переменная PROG и заканчива-
ется адресом, на который указывает систем-
ная переменная RAMTOP. Предположим, что Вы
хотите  записать  программу в машинных ко-
дах, начиная с адреса 30000. Дайте команду
CLEAR  29999. Эта команда установит RAMTOP
в 29999 и Ваша программа будет защищена от
возможной  порчи  из БЕЙСИКа. Даже если Вы
дадите  команду NEW, области памяти, нахо-
дящиеся выше RAMTOP, не будут поражены.
  Теперь  дайте две прямые команды одну за
другой:

POKE 30000,0
POKE 30001,201

  Мы  сейчас  записали  два числа в нужные
нам  адреса. Они образуют простейшую прог-
рамму.  Выполнить ее можно командой RANDO-
MIZE USR 30000. Попробуйте сами... Вам по-
кажется,  что  ничего не произошло, но это
не так. Сначала процессор обратился по ад-
ресу  30000  и  нашел там число 0, которое
обозначает машинный код операции NOP. Опе-
рация  NOP  (NO  OPERATION - нет операции)
дает команду процессору, что ничего делать
не надо. В течение 0,0000014 сек. он дейс-
твительно  ничего не делает, а затем пере-
ходит к следующему адресу, где находит

исло 201.
  Это  команда RET (RETURN - возврат). Она
дает процессору указание прекратить в этом
месте  программу  в  машинных кодах и вер-
нуться туда, откуда она вызывалась, т.е. в
нашем случае - в БЕЙСИК. Это самое процес-
сор  и сделал, о чем Вы получили сообщение
БЕЙСИКа "О.К.".
  Если  все,  что  Вы здесь прочитали, Вам
понятно, то Вы уже поняли, как составляют-
ся  программы в машинных кодах. Можно, ко-
нечно,  возразить,  что  пользы  от  такой
программы  не  очень много, но сейчас не в
этом суть. Важно, чтобы Вы поняли, что не-
кая  последовательность  чисел  может быть
последовательностью  команд для процессора
Z-80.
  К  сожалению,  для  нас мало что говорит
простая последовательность чисел вроде та-
ких,  как  0  и 201. Держать в памяти коды
всех  команд  процессора (а их около семи-
сот) непросто, но дело упрощается тем, что
есть  промежуточный язык между процессором
и  человеком  - язык АССЕМБЛЕРа. У каждого
кода  есть своя мнемоника АССЕМБЛЕРа. Мне-
моника - это набор букв, являющихся сокра-
щением английских слов. Для нашего примера
программа на АССЕМБЛЕРе выглядит так:

                   NOP
                   RET

  Перевод  этих  мнемоник  в машинные коды
тоже  можно поручить компьютеру. Для этого
существуют  специальные программы, которые
тоже  называют АССЕМБЛЕРами. Есть и проти-
воположные  программы - ДИСАССЕМБЛЕРы. Они
наоборот  переводят машинные коды в мнемо-
ники АССЕМБЛЕРа.
  И  тех программ и других достаточно мно-
го. Часто они объединяются в пакеты. Широ-
ко распространены пакеты GENS3/MONS3 фирмы
HISOFT и EDITAS/MONITOR 16/48 фирмы PICTU-
RESQUE. Здесь GENS3 и EDITAS - АССЕМБЛЕРы,
а  MONS3, MONITOR 16 и MONITOR 48 - ДИСАС-
СЕМБЛЕРы.
  Теперь  давайте  вернемся к нашей первой
программе  и  попробуем  ее несколько раз-
вить, чтобы она все же что-то делала. Про-
цессор  Z-80  имеет несколько регистров, у
которых  есть имена - "А", "В", "С" и т.д.
Каждый  из них может содержать одно какое-
либо  целое  число  от 0 до 255 (т.е. один
байт).
  Существуют  десятки  команд  процессора,
которые  позволяют  копировать  содержимое
регистров  из одного в другой, а также вы-
полнять  связь с внешним миром, в т.ч. и с
оперативной памятью.
  Так, например, команда АССЕМБЛЕРа LD B,A
(машинный  код  -  71) означает "загрузить
содержимое  регистра  А в регистр В". LD -
это сокращение от LOAD (LOAD - ЗАГРУЗКА).
  Точно  так  же  LD C,B (машинный код 72)
означает "загрузить в регистр С содержимое
регистра  В". Можно загружать в регистры и
целые  числа.  Например, LD A,N - означает
"загрузить  в регистр А целое число N, где
N может быть числом от 0 до 255". До этого
все  команды были однобайтными. Эта же ко-
манда - двухбайтная. Сначала идет машинный
код  -  62,  а за ним само число - N. Так,
например,  LD  A,77 (загрузить в регистр А
число  77)  будет  выглядеть  так:  62,77.
Здесь  62  -  код  операции, - он сообщает
процессору,  что  надо сделать, а 77 - это
операнд. Заметим здесь же, что бывают опе-
рации и трехбайтные и четырехбайтные. Пер-
вый  байт,  как правило, - код операции, а
следующие  за  ним  - операнды. Мы говорим
"как  правило"  потому, что есть некоторые
операции,  код  которых записывается двумя
байтами /1.
  Итак,  мы уже готовы к тому, чтобы напи-
сать  программу,  которая будет перебрасы-
вать  какое-либо  число из одного регистра
процессора в другой.
──────────────────────────────────────────
/1  ИСТОРИЧЕСКАЯ  СПРАВКА:  Процессор Z-80
разрабатывался  на основе своего предшест-
венника,  процессора 8080. Большинство ко-
манд у них совпадают, но для Z-80 было до-
бавлено  несколько  десятков новых команд.
Чтобы  их отличить от команд 8080, они на-
чинаются  с префикса 203, 221, 237 или 253
(в шестнадцатиричном коде, соответственно:
CB, DD, ED или FD). Поэтому появились опе-
рации, код которых состоит из двух байтов,
за которыми следуют операнды.

АССЕМБЛЕР                   МАШИННЫЙ КОД
NOP                         30000      0
LD A,77                     30001      62
                            30002      77
LD B,A                      30003      71
LD C,B                      30004      72
RET                         30005      201

  Гораздо  интереснее было бы организовать
обмен  между процессором и оперативной па-
мятью компьютера. Команд, которые позволя-
ют  это  сделать, тоже очень много. Напри-
мер,  это  команда  LD (NN),A. Ее машинный
код  - 50. Она означает следующее: "Загру-
зить  в ячейку памяти, адрес которой задан
двухбайтным числом NN, содержимое регистра
A". Эта команда - трехбайтная. Первым идет
код  операции (50), а за ним - двухбайтный
операнд  NN, который задает нужный Вам ад-
рес. Например, если Вам нужен адрес 30008,
то  тогда  операнд NN будет иметь вид: 56,
117 потому, что 117*256 + 56 = 30008.
  Этот  двухбайтный  операнд имеет старшую
часть  и младшую. Запомните, что двухбайт-
ные  числа  (как правило, это адреса) хра-
нятся  в памяти всегда в обратном порядке,
т.е. сначала младший байт, а потом старший
/1.
  Таким  образом,  команда  АССЕМБЛЕРа  LD
(30008),A  в машинных кодах запишется так:
50, 56, 117.
  Существует  и противоположная команда LD
A,(NN) - "Загрузить в регистр А содержимое
ячейки  памяти,  заданной  адресом NN". Ее
код  -  58,  за которым следуют два байта,
указывающие  на  адрес: сначала младший, а
потом  - старший. Тогда LD A,(30007) запи-
шется так: 58, 55, 117.
  Теперь  мы уже можем перемещать содержи-
мое  ячеек памяти из одной в другую, копи-
руя его через регистр А процессора.
──────────────────────────────────────────
/1  ИСТОРИЧЕСКАЯ  СПРАВКА:  Наш  житейский
опыт учит, что сначала идут старшие разря-
ды, а потом младшие. Например, в числе 567
сначала  идут  сотни  (5), потом - десятки
(6)  и только затем единицы (7). В компью-
тере  -  наоборот.  Это связано с тем, что
первые  компьютеры  имели  такую маленькую
память,  что о старших разрядах речь тогда
и не шла. Они явились более поздним допол-
нением и им пришлось занять не первое мес-
то.
  Теперь  мы уже можем перемещать содержи-
мое  ячеек памяти из одной в другую, копи-
руя его через регистр А процессора.

               До операции
┌─────┐                            ┌─────┐
│30007│                            │30008│
├─────┤┌──┬──┬──┬──┬──┬──┬──┬──┬──┐├─────┤
│  N  ││A │. │. │. │. │. │. │. │. ││  -  │
└─────┘├──┴──┴──┴──┴──┴──┴──┴──┴──┤└─────┘
       │П  Р  О  Ц  Е  С  С  О  Р │
       └──────────────────────────┘

              После операции
┌─────┐                            ┌─────┐
│30007│                            │30008│
├─────┤                            ├─────┤
│  N  │                            │  N  │
└─────┘                            └─────┘

АССЕМБЛЕР                  МАШИННЫЙ КОД

LD A,(30007)                30000    58
                            30001    55
                            30002    117
LD (30008),A                30003    50
                            30004    56
                            30005    117
RET                         30006    201

  Можно  еще  несколько усложнить задачу и
попытаться  выполнить сложение содержимого
двух  каких-либо  ячеек памяти и отправить
результат на хранение в какую-либо ячейку.
Для  выполнения  арифметических  действий,
например  сложения,  процессор  Z-80 также
имеет несколько команд. Рассмотрим команду
ADD A,B (ее машинный код - 128). ADD = AD-
DITION = СЛОЖЕНИЕ.
  ADD  A,B  означает следующее: "Прибавить
содержимое  регистра B процессора к содер-
жимому  регистра  А и результат оставить в
регистре А".
  Как  видите,  эта  команда  однобайтная,
т.к. все указания на то, что откуда взять,
что с ним сделать и куда отправить резуль-
тат, в ней есть уже сами собой.
  Предположим,  что  Вы хотите сложить со-
держимое  ячеек 30013 и 30014, а результат
поместить  а ячейку 30015. Тогда программа
на  АССЕМБЛЕРе  и  в  машинных кодах будет
иметь вид:

АССЕМБЛЕР    МАШИННЫЙ КОД КОММЕНТАРИЙ
LD A,(30013) 30000    58  Загрузить  в ре-
                          гистр  А  число,
             30001    61  содержащееся   в
             30002    117 адресе 30013.
LD B,A       30003    71  Загрузить в  ре-
                          гистр В содержи-
                          мое регистра А
LD A,(30014) 30004    58  Загрузить в ре-
                          гистр А  число,
             30005    62  содержащееся   в
             30006    117 адресе 30014.
ADD A,B      30007    128 Прибавить  к со-
                          держимому  А со-
                          держимое регист-
                          ра В.
LD (30015),A 30008    50  Выгрузить содер-
             30009    63  жимое регистра A
             30010    117 в адрес 30015.
NOP          30011    0   Нет операции.
RET          30012    201 Возврат туда,от-
                          куда   эта  про-
                          грамма   вызыва-
                          лась.

  Попробуйте эту программу в работе. Пусть
Вы  хотите  сложить два числа, скажем 50 и
70.  Сначала выделим память для этой прог-
раммы в машинных кодах.

10 CLEAR 29999

  Теперь  введем  эту  программу в память,
начиная с адреса 30000.

20 FOR i=30000 TO 30012: READ q: POKE i,q:
NEXT i
30 DATA 58, 61, 117, 71, 58, 62, 117, 128,
50, 63, 117, 0, 201

  Запишем  в  ячейки  30013 и 30014 те два
числа, которые мы желаем сложить:

40 POKE 30013, 50: POKE 30014, 70

  Введем команду на исполнение нашей прог-
раммы в машинных кодах.

50 RANDOMIZE USR 30000

  И,  наконец,  стартуем нашу БЕЙСИК-прог-
рамму - RUN.
  Через  долю  секунды она отработает и на
экране  появится  сообщение  О.К. Вроде бы
ничего  не изменилось, но если Вы провери-
те,  что находится в ячейке 30015, то убе-
дитесь, что там находится результат сложе-
ния, т.е. число 120.

PRINT PEEK 30015   даст Вам:     120  О.К.

  Итак, мы уже познакомились с несколькими
командами процессора Z-80. Теперь нам при-
дется прервать такое сверхпопулярное изло-
жение, поскольку система команд этого про-
цессора  довольно обширна и при таком под-
ходе  пришлось  бы отвести ей около тысячи
страниц.  Мы надеемся, что психологический
барьер  Вы уже преодолели и далее мы пере-
ходим  к  систематическому  и постепенному
освоению системы команд процессора.
  Вы,  по-видимому, поняли, что всякой ко-
манде  в машинных кодах соответствует своя
мнемоника АССЕМБЛЕРа, в которой в несколь-
ких  буквах  зашифрована  суть операции. К
сожалению, обычно литературу пишут профес-
сионалы для профессионалов и они не утруж-
дают  себя  переводом  мнемоник на русский
язык, тем более, что по Z-80 книг на русс-
ком  языке  почти  нет (есть несколько ве-
домственных переводов). Поэтому "Инфорком"
в  своем  "Справочнике.." (часть 3) уделил
место  словарю  для  перевода мнемоник АС-
СЕМБЛЕРа  в нормальный английский, а через
него и в русский язык.
  В  заключение этой главы несколько общих
замечаний. Различные процессоры имеют раз-
личные  системы команд. Знание системы ко-
манд  процессора Z-80 еще не означает, что
Вы  сможете  разбираться  в  машинном коде
других  компьютеров,  собранных  на других
процессорах,  но  совершенно точно, что их
освоение пройдет у Вас в десятки раз быст-
рее.
  Даже  для  одного только процессора Z-80
мнемоники до сих пор не стандартизированы.
Многие ассемблирующие программы, например,
EDITAS,  ZEUS,  GENS1...GENS3  и др. имеют
отклонения в форме записи мнемоник, но они
незначительны  и  всегда  оговариваются  в
сопроводительной инструкции к программе.

──────────────────────────────────────────
Тексты предоставлены Михаилом (MIHEICH)
                                10.07.1999



Другие статьи номера:

AD&D - Значение способностей.

Проходилка - прохождение игры Magician land.

Учебник - Программирование в машинных кодах и на языке АССЕМБЛЕРА (часть первая).


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

Похожие статьи:
Дикий ум - Компрессия: Фичи с эвристикой, Потоковая декомпрессия, Сжатие музыки (часть 2).
For Coderz - Маленькие программерские хитрости.
For Coderz - Макросы под ассемблер Alasm v4.4x.

В этот день...   13 декабря