27 ноября 1998 |
|
Краткий урок ассемблера для ламеров Alone Coder Предисловие. До недавнего времени я полагал, что на свете уже не сущестувует людей, которые не только не могут написать компьютерную иг- ру, но и - страшно сказать! - не могут от- личить регистр от порта. Мои наивные пред- положения развеял недавний визит на рязан- ский радиорынок в ЦПКиО. - У вас есть какие-нибудь программы для Синклера?- спросил молодой человек,подойдя к столу в центре площадки. Меня насторожило уже слово <Синклер>: может быть, кто-то еще не знает, но компь- ютер, на котором Вы читаете этот текст,на- зывается ZX Spectrum, от латинского слова, означающего, кажется, <радуга>. Я подошел ближе. - Извините, я местный кодер. Меня зовут Дима Быстров...- начал я смущенно. Разговорившись,мы обменялись адресами и простились, пообещав навещать друг друга. Через пару недель мы снова встретились; каждая моя программа явно удивила моего нового знакомого,который,вероятно,не видел свежего софта уже года два. Я скинул ему основных утилит и пожелал в скором времени написать что-нибудь хорошее. Прошло еще две недели... Он вернул мои диски и принес старый журнал в глянцевой обложке. Журнал назывался <Домашний компьютер>; это был, по правде говоря, писюшный журнал (<писюшный>- прилагательное от <писи>, ка- ковой термин мы, кодеры, используем вместо IBM PC). Рубрика <ПОМОГИТЕ!> наиболее заи- нтересовала меня. Это рубрика вопросов чи- тателей журнала и ответов на них, данных неким д-ром Хелпом. Когда я натолкнулся на ЭТИ вопросы,я не смог удержаться от смеха: <Я внимательно посмотрел на свой компьютер сзади и обнаружил там несколько интересных разъемов. Интересно, что это за разъемы и можно ли их как-то использовать? Мышь и принтер у меня уже подключены. Что можно еще подключить?> <Очень я люблю играть в игры,но играю все- гда один.Друзья мне рассказали,что во мно- гие компьютерные игры можно играть двум игрокам одновременно на разных компьюте- рах. При этом будто бы можно сражаться на разных сторонах.Как это бывает?Мне никогда не приходилось в такие игры играть>. Следующий вопрос я специально отмечаю. Теперь Вы поймете, к чему я вообще повел эту беседу. Готовьтесь... <Я недавно купил компьютер.Но пользоваться им я боюсь. Не потому,что я боюсь техники. Просто я не знаю,что надо делать,чтобы из- бежать поломок? Компьютерная техника дово- льно сложная,непонятная и совсем не похожа на другую технику. Я больше всего опасаюсь чего-нибудь поломать или испортить>. Далее следует описание того, как компь- тер следует пылесосить и протирать тряпоч- кой. Но самого главного авторы журнала не смогли понять: читатель ПОЛАГАЕТ, ЧТО АП- ПАРАТНУЮ ЧАСТЬ КОМПЬЮТЕРА МОЖНО ИСПОРТИТЬ, НАЖАВ НЕ НА ТУ КНОПКУ! Развеять подобные мифы и помочь чудако- ватым читателям компьютерных журналов по- чувствовать себя хозяевами своего компью- тера и должна эта страничка. Глава 1 о том, как побороть страх и написать простейшую программу на ассемблере Во-первых, введу несколько основных по- нятий,используемых нами и применения кото- рых Вам в будущем не избежать. КОДЕР - человек, который пишет (делает) программы в машинных кодах. МАШИННЫЕ КОДЫ - указания процессору Z80 в компьютере,сводящиеся к простейшим вычи- слительным операциям. Программы в машинных кодах ВСЕГДА быстрее написанных на каких- либо других языках(Бейсик,Паскаль,Си,...). АССЕМБЛЕР (АСМ) - метод записи М.К. на бумаге(экране,диске,..)в виде букв и цифр. Также А.- программа, которая переводит асм в М.К. ЛАМЕР - не КОДЕР. Также Л.- тот,кто лю- бит портить чужие программы. ХАКЕР - хороший КОДЕР, который изменяет чужую программу в лучшую сторону(например, вставляет вечную жизнь, красивую заставку, упаковывает игру,редко - исправляет ошибки в программе или добавляет к ней новые воз- можности). ПАМЯТЬ - память компьютера. В более уз- ком смысле - оперативная память(ОЗУ, в нее еще можно записывать). БАЙТ - символ/ число от 0 до 255/ число от -128 до 127, причем -128 соответствует 128, -127 соответствует 129, и.т.д. Из них состоит память. БИТ - одна восьмая байта.Содержит мини- мум информации:0 или 1.(Несмотря на беско- нечные повторения этой бессмысленной фразы в литературе, спешу сообщить, что минимум информации - это ноль бит,а если Вы скаже- те, что так не считается, то приведу еще пример меньшей информации:0 с вероятностью 1/3 или 1 с вероятностью 2/3.) Нумеруются в байте справа налево с нуля, причем сумма битов, помноженных на двойки в степени их номеров, даст значение байта. Лучшим Ассемблером является ALASM. Он имеет 2 режима - командный и редак- тирования. Первый устанавливается после загрузки. Вход во второй - набрать EDIT (кнопка Е) название. Например: EDIT ААА. Тут же Вы войдете в новоиспеченный тек- стовый файл ААА.H и сможете его изменить. Теперь Вы сидите перед экраном,а голова Ваша почему-то стала плохо соображать. В таких случаях я набираю первую и последнюю строчки будущей программы.Вот как они обы- чно выглядят: ORG 25000 RET Первая указывает место в памяти,где бу- дет работать программа (от 24576 до 65535) и не является командой процессору (то есть не занимает места). Последняя - выход из программы(или из подпрограммы,что в сущно- сти то же самое)туда, откуда ее осмелились запустить(вызвать). Команды типа ORG называются директивами Ассемблера. Еще пример директивы: ENT Она нужна для того,чтобы знать,с какого места запустить Вашу изобилующую ORG'ами программу,поскольку одни Ассемблеры (MASM) предпочитают последний ORG,другие (ALASM)- первый, а некоторые - вообще отказываются транслировать(ассемблировать)программу без ENT или ENT $. Строчки для вставления команд в середи- ну текста раздвигаются кнопками SS+W (<>), а сдвигаются кнопками SS+Q (<=). Сначала это может показаться неудобным,но потом Вы найдете это весьма хорошим способом. Полезна директива DEFB "text",#3F,5,"a" Она засовывает в то место памяти, где должна была бы располагаться следующая ко- манда программы,любой набор байтов (симво- лов). Аналогична команда DEFW, но она сует байты по два и не переваривает текстов.Еще загадочнее команда DEFS 40,1,2,3 - которая 40 раз подряд пихает в память байты 1,2,3. Решетка # означает шестнадцатиричное число #3F=3*16+F, где A,B,C,D,E,F соответственно равны 10,11,12,13,14,15. Но я отвлекся. Чтобы наша программа де- лала хоть что-то, хотя мы еще ничего не умеем, нагло используем какую-нибудь чужую программу из ПЗУ (там много интересного): ORG 25000 CALL 3582 RET Теперь мы вызываем программу сдвига всего экрана вверх на знакоместо(SCROLL UP CHR$) таким же образом, как нашу программу вызвала система (Бейсик,ALASM,TR-DOS,...). Чтобы запустить сей плагиат(дедовщину?) и посмотреть,как он работает,выйдем из ре- жима редактирования в режим команд. Для этого нажмите EXTEND;появится строчка ожи- дания команды редактора. Можно ввести раз- ные команды: B - начало текста, E - конец, S - поиск чего-нибудь, X - замена,и еще уж не помню что, но Вам надо нажать Q - Quit. Теперь программу стоит записать: SAVE. После этого ассемблируем: ASSEMBLE и запу- скаем: RUN. Экран сдвинулся вверх, ура. Можно также вызвать ее из Бейсика: QUIT (выход в Бейсик), RANDOMIZE USR 25000. Возврат в ALASM - RANDOMIZE USR 23600. Из встроенного отладчика StS: DEBUG (отладка),JUMP 25000. RANDOMIZE USR 23600. Переход в редактирование - EDIT. Для полного овладения системой Вам сто- ит прочитать HELP'ы к ALASM и StS.Дальней- ший текст для компактности предполагает, что Вы уже умеете с ними обращаться. Глава 2 обо всём понемножку Регистр является маленькой переменной, которая хранится не в памяти,а в процессо- ре. В регистре 1 байт. Названия регистров: A B C D E H L Я перечислил только регистры общего на- значения,всего же регистров 24.6 последних собраны в пары, которые называются просто <регистровыми парами>(reg pair,rp) и могут использоваться как двухбайтное число/адрес (из 160К памяти одновременно адресуются 64 К,посему адрес байта передается 2 байтами) Регистру можно присвоить значение командой LD E,100 или LD BC,40000 или LD A,H но не LD HL,BC Метка (label)аналогична номеру строки в Бейсике за тем ислючением, что ее не нужно помещать в каждой строке.Метку можно испо- льзовать в выражениях вместо соответствую- щего числа.Метка содержит 7 символов и на- чинается с буквы. Пример: ORG 25000 LD DE,TEXT LD BC,TEND-TEXT CALL #203C ;опять программа из ПЗУ RET TEXT DEFB "TEXT - это метка",13 TEND Печатается текст по адресу TEXT=25010 длиной TEND-TEXT=17 байт. Все эти вычисле- ния производит ALASM при трансляции. Если Вы не желаете, чтобы программа вы- полнялась только подряд,можно использовать переход к метке: ORG 25000 LD BC,#50F0;B=#50=80,C=#F0=240 JP 8933 На экране появляется точка. JP 8933 пе- редает управление программе в ПЗУ,которая, естественно,уже содержит RET,так что можно не волноваться по поводу возврата. Переход не более чем на 127 байт вперед/назад на- зывается коротким или относительным и за- писывается JR адрес. Когда нужно выполнить что-то несколько раз подряд(совершить цикл),в частности,ис- пользуется команда DJNZ адрес: ORG 25000 LD B,80 CYCLE LD (BUF),BC;запишем;8933 портит B LD C,B CALL 8933 LD BC,(BUF);в BC старое значение DJNZ CYCLE RET BUF DEFW 0 Нарисуется диагональ.DJNZ вычитает из B единицу и,если не получился ноль,переходит по указанному адресу. Легко подсчитать,что поэтому цикл выполнится ровно столько раз, сколько было в B при входе в него(т.е.80). Круглые скобки означают,что имеется в виду не число, а ячейка памяти с этим номером. LD (BUF),BC записывает BC по адресу BUF. Использовать ячейки с метками для хра- нения регистров неудобно,поэтому придуманы команды: PUSH rp(пихнуть) и POP rp(вытолк- нуть).Первая запоминает rp в области памя- ти, именуемой стеком, вторая берет оттуда текущее значение в rp. Много значений, за- сунутых в стек,снимаются оттуда в обратном порядке. Там же хранится адрес,по которому переходит команда RET. Поэтому число PUSH и POP должно совпадать. Пример: ORG 25000 LD B,80 CYCLE PUSH BC LD A,80 SUB B LD C,A CALL 8933 POP BC DJNZ CYCLE RET Нарисуется обратная диагональ. Команда SUB r относится к категории арифметическо- логических и вычитает из A регистр r. Дру- гие а-л команды: ADD A,r;прибавить r к A ADD HL,rp;прибавить rp к HL ADC A,r;A=A+r+CY ADC HL,rp;HL=HL+rp+CY SBC A,r;A=A-r-CY SBC HL,rp;HL=HL-rp-CY DEC r/rp;уменьшить rp на 1 INC r/rp;увеличить rp на 1 AND r;побитовое A И r записывается в A.Об- нуляются все биты A, которым соответствуют нулевые биты r. OR r;побитовое A ИЛИ r записывается в A. В единицу обращаются все биты A,соответству- ющие которым биты r были равны 1. XOR r;то же, но побитовое ИСКЛЮЧАЮЩЕЕ ИЛИ. B каждый бит A записывается 1, если биты с этим номером в A и r были разные;иначе 0. CP r;сравнение A с r CPL;A=255-A.Все биты инвертируются(01) NEG;А=-А. DAA;Двоично-десятичная коррекция; произво- дите ее сразу после сложения/вычитания,ес- ли с/в'емые числа были двоично-десятичные. Вряд ли она Вам пригодится,т.к.д-д числа - это метод записи двух цифр в байте, причем д-д #34 считается равным 34. Несколько слов о том,что же такое CY.Он называется флагом(признаком,битом)переноса и устанавливается в 1, если результат сло- жения превысил 255(65535 в случае 2-байто- вого сложения) или при вычитании большего числа из меньшего или в других особо ого- воренных случаях. Еще используется флаг Z, который равен 1, если результат а-л опера- ции равен нулю,и нулю в других случаях. За это он называется флагом нуля. Все флаги находятся в регистре флагов F,который вме- сте с регистром A составляет еще одну(чет- вертую)r.p.AF,которая,к сожалению,не может использоваться в двухбайтовых вычислениях. Сравнение - то же вычитание, но резуль- тат его не запоминается,а только соответс- твующим образом меняются флаги: Z=1,если A=r;Z=0,если A<>r; CY=1,если A,где cc - условие: Z - Z=1 Поскольку есть еще флаги,то есть NZ - Z=0 и дополнительные редко использу- C - CY=1 емые условия,употребляемые в ко- NC - CY=0 мандах длинного перехода JP. То есть,если условие выполнится,то сле- дует осуществить переход,иначе - нет. Глава 3 несколько важных практических советов Программа становится Вашей лишь тогда, когда Вы трудились над ее созданием. Кста- ти,не стоит также радоваться после написа- ния любой программы, если последняя до Вас была написана хотя бы одним человеком. Существует два способа написания прог- рамм на асме: на бумаге ручкой/карандашом с последующим набором на компьютере и не- посредственно сидя за/перед экраном.Первый способ хорош тем,что можно писать програм- мы вдали от компьютера и плох низкой прои- зводительностью и повышением числа ошибок; второй обходит недостатки первого и теряет его достоинства.Желательно владеть обеими. Несмотря на то,что Пентагон 128-й, пом- ните, что не каждый компьютер - Пентагон. Следовательно, не стоит пользоваться двумя экранами, когда довольно одного, а также жрать все 71680 тактов процессора или ста- вить первой командой прерывания EI. НИКОГДА не управляйте включением/выклю- чением дисковода для проверки наличия дис- ка или проигрывания через дисковод музыки! В отечественном дисководе 5313 при этом нарушается работа механизма опускания го- ловки на диск и дисковод НЕ МОЖЕТ ПИСАТЬ ИНФОРМАЦИЮ! Имейте копии своих важных программ на своих и/или чужих дисках. Последнее иногда даже надежнее. Не имейте копий барахла. Сохраняйте системную дорожку. Экономьте свое время, e.g. не смотрите дважды одни и те же телепередачи,не ходите на дискотеки и пьянки. Помните: жизнь у человека одна и короткая, а вспомнят о Вас лишь если Вы успеете сделать за нее много. Научитесь говорить, печатать, ходить и ду- мать быстро. Имейте терпение; ошибки в программах случаются и у мэтров из CodeBusters,но они умеют их исправлять=>и Вы научитесь.Сперва структуру сложной программы Вы не сумеете удержать в памяти,но через небольшое время регулярной работы на компьютере размер программы, набираемой зараз,станет неогра- ниченным. Не составляйте программу из кусочков! Метки в программах рекомендуется приду- мывать так: название подпрограммы+буква/ цифра, например: MOVTXT0 в п/п MOVTEXT; READKYQ в READKEY; можно SYMN13 в SYM. Если кто-то скажет Вам, что некий метод является всегда лучшим, не верьте ему. Для примера возьмем перемещение памяти.Медлен- ный LDIR незаменим в текстовом редакторе; LDI весьма полезен при вертикальном сдвиге экрана и недостатке памяти под сдвигалку; POP HL:LD (...),HL используется в сдвигах, мультиколорах и мэппингах;POP rp...PUSH rp хорошо для ускорения мэппинга (см.статью в следующем номере); LD rp,...PUSH rp доселе использовалось только для рисования сето- чек, хотя одним махом увеличивает ширину мультиколора до 24 CHR$ +позволяет вывести экран в одно прерывание (см.статью). Несмотря на то, что переключение двух изображений дает разнообразные графические режимы,помните,что это приводит к мерцанию экрана, которое,возможно,годится для демо, но не для программы, которую пользователь активно использует. Можно даже вспомнить: Quod licet Iovi,non licet bovi,что означа- ет<Что может Юпитер,то не позволено быку>. Переключение трех экранов не используйте никогда, поскольку это влечет за собой не мерцание, но моргание экрана. Не ограничивайте сложность составляемых Вами программ, оправдываясь тем, что некто является очень умным или у него больше свободного времени,чем у Вас. Не боги гор- шки обжигают! У меня вообще нет свободного времени, однако написал же я этот журнал! Продолжение следует...
Other articles:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Similar articles:
В этот день... 21 November