|
|
Строка 1: |
Строка 1: |
| {{ДИ}}
| | '''Материал удален по требованию автора.''' |
| {{TOCright}}
| |
| | |
| <pre>
| |
| 5.1. Отладчик MIRAGE
| |
| | |
| Система MIRAGE С.Зильберштейна (г.Киров) - одно из самых удобных
| |
| средств, облегчающих программирование в кодах на БК и отладку
| |
| программы в кодах. В комплект поставки входит описание системы и две
| |
| версии программы:
| |
| MIRAGE26 - загружается с адреса 26000 и позволяет работать с
| |
| программами в адресах ОЗУ 1000-25777;
| |
| MIRAGE - загружается в экранное ОЗУ с адреса 66000 и позволяет
| |
| работать с программами максимальной длины (вплоть до 37777). Платой за
| |
| эту возможность служит невозможность отладки программ со спрайтовой
| |
| графикой, поскольку они могут запортить отладчик, находящийся в
| |
| экранном ОЗУ.
| |
| Существует также версия этого отладчика, распространенная под
| |
| названием OS0010F, приспособленная П.Эльтерманом (г.Москва) для работы
| |
| с Фокалом (возможность перехода из Фокала в MIRAGE и обратно удобна
| |
| при написании и отладке программ типа "Фокод").
| |
| MIRAGE работает в двух основных режимах: командном и экранном.
| |
| При начальном запуске система находится в командном режиме. Здесь
| |
| можно давать команды работы с файлами, с памятью, команды
| |
| редактирования и трассировки отлаживаемой программы. При описании
| |
| команд используются обозначения "начало" и "конец" для обозначения
| |
| начального и конечного адреса, "имя" - имя файла при работе с
| |
| магнитофоном. Необязательные элементы заключены в квадратные скобки.
| |
| LOAD имя - загрузка файла с адреса, указанного на ленте;
| |
| LOAD имя/адрес - загрузка с указанного адреса;
| |
| SAVE имя/начало/конец - запись программы на магнитофон;
| |
| SAVE - запись программы на магнитофон с тем же именем, начальным и
| |
| конечным адресом, что были указаны в последней выполненной команде
| |
| SAVE;
| |
| SET имя - поиск файла на ленте;
| |
| DIR - просмотр названий файлов на ленте;
| |
| D адрес - пошаговый дамп содержимого ОЗУ с указанного адреса по
| |
| словам (распечатка в восьмеричной системе счисления);
| |
| D адрес/B - то же по байтам.
| |
| В режиме дампа действуют команды: "ВК" - продолжить дальше, "." -
| |
| окончить дамп и выйти в командный режим.
| |
| DR - распечатка содержимого регистров процессора R0-R5, SP, PC
| |
| и признаков PSW N,Z,V,C;
| |
| S адрес - пошаговый просмотр и изменение содержимого памяти,
| |
| начиная с указанного адреса по словам;
| |
| S адрес/B - то же по байтам;
| |
| SR - пошаговый просмотр и изменение регистров процессора.
| |
| В этих режимах можно, нажимая "ВК" или "стрелку вверх",
| |
| просматривать содержимое памяти соответственно в сторону увеличения
| |
| либо уменьшения адресов, а при необходимости внести изменения: набрать
| |
| новое значение слова (байта) в восьмеричной системе счисления и нажать
| |
| "ВК" или "стрелку вверх". "." - конец пошагового просмотра и выход в
| |
| командный режим. В режиме просмотра по байтам "S адрес/B" можно
| |
| вводить строку символов, начинающуюся кавычками.
| |
| F начало/конец/код - заполнение указанного участка ОЗУ значением
| |
| "код";
| |
| M начало/конец/адрес - побайтное копирование участка ОЗУ, заданного
| |
| начальным и конечным адресом, в область, начиная с указанного адреса;
| |
| C начало/конец/адрес - пословное сравнение двух участков ОЗУ
| |
| одинаковой длины: один задан начальным и конечным адресом, второй
| |
| начинается с указанного адреса;
| |
| W начало/конец/слово[/маска] - поиск "слова" в указанном участке
| |
| ОЗУ. Если задана "маска", то ведется поиск всех слов, которые
| |
| совпадают с образцом поиска ("словом") только в тех битах, которые
| |
| установлены в маске. Например:
| |
| W 1000/2000/123 - найти и указать адреса слов в диапазоне от 1000
| |
| до 2000, в которых записано значение 123;
| |
| W 1000/2000/177600/177600 - найти в указанном диапазоне все
| |
| обращения к системным регистрам, то есть слова, значения которых лежат
| |
| в диапазоне от 177600 до 177777. Учтите при этом, что MIRAGE не может
| |
| в подобных случаях отличить адрес (то, что нам и надо) от данных (что
| |
| мы вовсе не имели в виду, давая эту команду). В каждом конкретном
| |
| случае разбираться приходится самому программисту.
| |
| W начало/конец/адрес[/маска]/R - поиск относительных ссылок на
| |
| указанный адрес (или интервал адресов, определенный маской). Например,
| |
| у нас есть кусок программы:
| |
| | |
| 1000: 167 JMP 4000
| |
| 1002: 2774
| |
| | |
| где применена относительная адресация в команде перехода. Если мы
| |
| дадим в MIRAGE команду "W 1000/1010/4000/R", то получим сообщение:
| |
| | |
| 001002: 004000
| |
| | |
| из которого ясно, что по адресу 1002 найдена относительная ссылка на
| |
| адрес 4000.
| |
| U начало/конец - подсчитать контрольную сумму в указанном участке.
| |
| G [начало][/конец] - запуск программы с начального адреса (или с
| |
| текущего содержимого PC, если "начало" не указано) до конечного
| |
| адреса. Если "конец" не указан, то управление системе MIRAGE вернется
| |
| по команде HALT в отлаживаемой программе либо по прерыванию ее по
| |
| ошибке или по клавише "СТОП".
| |
| T [адрес] - пошаговая трассировка программы с указанного адреса
| |
| (либо с текущего содержимого PC). В процессе трассировки
| |
| распечатываются текущие значения регистров R0-R5, SP, PC и признаки
| |
| PSW N,Z,V,C, затем очередная команда, на которую показывает PC. "ВК" -
| |
| продолжение трассировки, "." или "СТОП" - окончание и выход в
| |
| командный режим.
| |
| R адрес - вызов подпрограммы с указанного адреса. MIRAGE вернется в
| |
| командный режим по достижении команды возврата из подпрограммы RTS PC.
| |
| A начало[/конец] - перейти к экранному редактированию программы в
| |
| указанном диапазоне адресов; при этом на экране отображаются адреса и
| |
| мнемоника команд;
| |
| ASM начало[/конец] - перейти к экранному редактированию программы в
| |
| указанном диапазоне адресов; при этом на экране отображаются адреса,
| |
| коды и мнемоника команд.
| |
| В режиме экранного редактирования MIRAGE дизассемблирует часть ОЗУ
| |
| (то есть переводит коды команд в их ассемблерные мнемоники). Если в
| |
| этом участке встречаются данные, то они также считаются командами и
| |
| будут дизассемблированы. Естественно, есть такие коды, которые не
| |
| соответствуют ни одной команде процессора; в этом случае пишется
| |
| мнемоника WORD (слово) и содержимое этого слова. По обилию мнемоник
| |
| WORD среди прочих правдоподобно выглядящих ассемблерных команд можно
| |
| распознать массивы данных в программе.
| |
| MIRAGE для удобства программиста заменяет команды "JSR PC,адрес" на
| |
| "CALL адрес" и "RTS PC" на "RET"; а для удобства ввода кода символа
| |
| позволяет писать команды вида "MOV #'A,R0", что тут же переведет в
| |
| "MOV #101,R0".
| |
| В режиме экранного редактирования можно редактировать мнемоники
| |
| команд с помощью клавиш управления курсором; все сделанные в данной
| |
| строке изменения будут приняты только после нажатия "ВК" в момент,
| |
| когда курсор стоит в этой строке. Редактор работает только в режиме 64
| |
| символа в строке; нельзя также допускать выхода курсора за пределы
| |
| экрана !
| |
| В режиме экранного редактирования действуют клавиши:
| |
| "КТ" - листание текста на экран вперед;
| |
| "СУ/Т" - листание на один экран назад (только после "КТ");
| |
| "ШАГ" - возврат к первому листу (с адреса, указанного в команде
| |
| ASM);
| |
| "ВС" - вставка команды NOP под курсором (нужно всегда учитывать
| |
| размер команды, которую Вы желаете вставить, и вставлять для этого
| |
| столько NOP-ов, сколько слов содержит команда. Об этом надо помнить и
| |
| при редактировании старой команды);
| |
| "СБР" - удалить команду под курсором;
| |
| "СТОП" - выход в командный режим.
| |
| Рассмотрим пример работы с системой MIRAGE. Попробуем набрать
| |
| программу буквально из нескольких команд. Загрузим MIRAGE26 и запустим
| |
| его. Очистим командой "F 1000/2000/0" участок ОЗУ с адреса 1000 до
| |
| адреса 2000 и будем здесь набирать нашу программу. Для этого перейдем
| |
| в режим экранного редактирования командой "ASM 1000" и увидим:
| |
| | |
| 1000: 000000 HALT
| |
| 1002: 000000 HALT
| |
| 1004: . . .
| |
| | |
| Это - наша, еще пустая, рабочая область. Никакого труда, вероятно,
| |
| не составит набрать такую короткую программу (нажимая "ВК" после ввода
| |
| каждой команды):
| |
| | |
| 1000: 010100 MOV R1,R0
| |
| 1002: 104016 EMT 16
| |
| 1004: 000775 BR 1000
| |
| | |
| Предположим, мы хотим заменить первую команду на команду "MOV
| |
| #101,R0". Учитывая, что эта команда займет два слова, а в нашем
| |
| распоряжении только одно, надо поставить курсор на вторую строку и
| |
| клавишей "ВС" вставить пустую команду. Программа приобретет вид:
| |
| | |
| 1000: 010100 MOV R1,R0
| |
| 1002: 000240 NOP
| |
| 1004: 104016 EMT 16
| |
| 1006: 000775 BR 1002
| |
| | |
| Теперь подведем курсор к первой строке, заменим "R1" на "#101" и
| |
| нажмем "ВК". Программа примет вид:
| |
| | |
| 1000: 010100 000101 MOV #101,R0
| |
| 1004: 104016 EMT 16
| |
| 1006: 000775 BR 1002
| |
| | |
| Мы видим, что команда "MOV #101,R0" заняла два слова памяти и
| |
| "съела" при этом вставленную команду "NOP". Если бы мы ее не вставили,
| |
| пропала бы следующая команда "EMT 16".
| |
| Теперь осталось внести последнее исправление. В команде перехода
| |
| использована относительная адресация, и, сдвинутая со старого места в
| |
| ОЗУ, команда перехода показывает уже не на тот адрес. Поэтому при
| |
| вставке или удалении команд приходится вручную корректировать адреса в
| |
| сдвинутых командах перехода. Это самое большое неудобство при работе с
| |
| подобными отладчиками. Можно посоветовать всегда иметь перед собой
| |
| текст программы на бумаге и в процессе работы вносить туда все
| |
| необходимые изменения. Нужно также иметь отдельную таблицу, в которой
| |
| перечислены адреса используемых Вами подпрограмм и глобальных
| |
| переменных. Такая таблица очень поможет Вам в работе.
| |
| Еще один полезный совет заключается в правильном использовании
| |
| режимов адресации. Отлаживая программу по частям или по отдельным
| |
| подпрограммам, старайтесь, чтобы все переходы внутри этого кусочка
| |
| использовали относительную адресацию. Тогда после отладки данной
| |
| подпрограммы ее можно будет перемещать в ОЗУ, заботясь только об
| |
| изменении ссылок на глобальные имена - на внешние подпрограммы и
| |
| переменные, которые к данному кусочку программы не привязаны.
| |
| Теперь давайте попробуем запустить нашу программу. Для этого нажмем
| |
| "СТОП" - MIRAGE26 перейдет в командный режим. Запустим программу
| |
| командой "G 1000". И она заработает - начнет выводить на экран букву
| |
| "А" (это ее код - 101). Чтобы остановить нашу зацикленную программу,
| |
| нажмем "СТОП" и вновь окажемся в командном режиме.
| |
| | |
| 5.2. Отладчики типа ГРОТ
| |
| | |
| Распространено много версий отладчиков под разными названиями (ОТЛ,
| |
| ОТЛАДЧИК3, ГРОТ и др.), которые по существу представляют собой одно и
| |
| то же. Коротко опишем версию, в командной строке которой появляется
| |
| надпись "Микро-отладчик <V1.1 860702 Москва-Рига>".
| |
| По своему принципу действия этот отладчик аналогичен системе
| |
| MIRAGE, но имеет несколько меньшие возможности и менее удобен в
| |
| работе. Он не имеет экранного редактора и удобной функции вставки-
| |
| удаления команд. На экране его отображается адрес, мнемоника команды,
| |
| ее коды по словам и по байтам, а также содержимое байтов в символьном
| |
| виде:
| |
| | |
| 1000 MOV #101,R0 012700 25.300 Ю
| |
| 000101 0.101 А
| |
| 1004 EMT 16 104016 210.16
| |
| 1006 HALT 000000 0.0
| |
| | |
| В правом верхнем углу выводятся текущие значения регистров
| |
| процессора и признаков N,Z,V,C.
| |
| Команды отладчика:
| |
| адресА - установить текущее значение адреса (как в ТС-отладчике);
| |
| К - выход в пусковой монитор;
| |
| , (запятая) - перемещение текущего адреса на команду вперед;
| |
| - (минус) - перемещение текущего адреса на команду назад;
| |
| I - вывести мнемонику команды по текущему адресу;
| |
| "ВК" - ввести мнемонику команды и записать ее по текущему адресу;
| |
| nD - сделать дамп n байт памяти с текущего адреса;
| |
| nL - распечатать n команд с текущего адреса;
| |
| конецPадрес - скопировать область ОЗУ с текущего по конечный адрес
| |
| в область, начинающуюся с указанного адреса;
| |
| R - вывод регистров процессора;
| |
| значениеRn - записать "значение" в регистр Rn;
| |
| О - очистить рабочие переменные отладчика;
| |
| адресG - запустить программу с указанного адреса; управление
| |
| вернется отладчику по команде HALT или другому аварийному прерыванию,
| |
| либо по установленной контрольной точке;
| |
| адресТ - установить контрольную точку - адрес команды, где
| |
| программа должна остановиться при отладке;
| |
| T - снятие контрольной точки;
| |
| адрес[ - пошаговая трассировка программы;
| |
| адресY - медленная автоматическая трассировка (1 команды в 5 сек.);
| |
| адрес] - ускоренная автоматическая трассировка (1 команда в сек.).
| |
| Если в этих командах не указать адрес, то выполнение начнется с
| |
| команды, на которую указывает PC.
| |
| адресЧ - чтение программы с магнитофона;
| |
| адресЗдлина - запись программы на магнитофон.
| |
| | |
| 5.3. Ассемблер МИКРО
| |
| | |
| 5.3.1. Описание языка
| |
| | |
| Работа с помощью описанных отладчиков очень близка к
| |
| программированию в машинных кодах. Отладчики представляют собой первую
| |
| ступень механизации программирования в кодах - замену кодов машинных
| |
| команд удобными для человека их мнемоническими обозначениями. Вся же
| |
| работа по распределению памяти, учету адресов лежит по-прежнему на
| |
| программисте.
| |
| Второй ступенью механизации программирования является программиро-
| |
| вание на языке низкого (машинного) уровня - языке ассемблера. Как и
| |
| система команд, свой язык ассемблера характерен для каждого типа ЭВМ.
| |
| Что же принципиально новое дает программисту язык ассемблера ? Прежде
| |
| всего, он позволяет использовать метки в тексте программы. Метки
| |
| используются для указания адреса в операциях перехода и пересылки. В
| |
| этом отношении они похожи на номера строк Бейсика или Фокала. Теперь
| |
| программист избавлен от необходимости учета физических адресов памяти,
| |
| он работает только с метками, а адрес получается при трансляции
| |
| ассемблерной программы. Если Вы добавите или удалите несколько команд,
| |
| то Вам не придется корректировать адреса в сдвинутых с места командах
| |
| перехода. Просто текст программы надо оттранслировать заново.
| |
| Для перевода программы на языке ассемблера в машинные коды
| |
| используется специальная программа, называемая ассемблером. Процесс
| |
| перевода называется ассемблированием. На ЭВМ ДВК, СМ используется
| |
| мощный ассемблер MACRO, имеющий очень много облегчающих работу
| |
| программиста средств (макрокоманды, условная трансляция и др.). На БК
| |
| используются ассемблеры попроще. Наибольшее распространение получила
| |
| система МИКРО, разработанная С.В.Шмытовым, А.Н.Сомовым и
| |
| С.А.Кумандиным (г.Москва). Ассемблер МИКРО включает в себя редактор
| |
| текста, транслятор и компоновщик, которые объединяет командный
| |
| монитор. Распространено несколько версий системы: МИКРО8С, МИКРО9,
| |
| МИКРО10, МИКРО11. Особенности каждой новой версии отражаются в
| |
| соответствующем описании. Здесь приведены основные сведения по МИКРО9.
| |
| Основные характеристики системы следующие:
| |
| - объем ОЗУ, занимаемый системой - 4.5К;
| |
| - максимальный объем исходного текста - 8К;
| |
| - максимальный размер транслируемой за один раз программы - 2К;
| |
| - максимальный размер программы, полученной при компоновке в
| |
| режиме РП - 16.5К.
| |
| Работа с системой будет описана ниже, а пока познакомимся с языком
| |
| ассемблера БК и его особенностями в системе МИКРО.
| |
| Программа на языке ассемблера, как и программа на Бейсике, состоит
| |
| из строк (операторов). В одной строке может быть записана одна команда
| |
| в обычной ассемблерной мнемонике, либо комментарий.
| |
| Строка программы (оператор) может состоять из 4-х частей (полей).
| |
| На рис.24 приведен пример оператора на языке ассемблера с обозначением
| |
| полей.
| |
| TT: MOV R1,R4 ;Пересылка
| |
| └─┬─┘ └─┬──┘ └────┬┘ └─┬────────┘
| |
| Метка Операция Операнды Комментарий
| |
| Рис. 24. Формат оператора на языке ассемблера
| |
| | |
| Поля "метка" и "комментарий" не являются обязательными частями
| |
| оператора.
| |
| Имя метки состоит не более, чем из трех символов (букв латинского
| |
| алфавита и цифр) и заканчивается двоеточием. В данном примере имя
| |
| метки состоит из двух букв "ТТ". Меткой обычно "метится" тот оператор,
| |
| к которому есть передача управления из какого-либо места программы.
| |
| Для хранения значений переменных используются определенные слова
| |
| памяти, которые также обычно "метятся" метками - тогда каждая метка
| |
| является именем соответствующей переменной. Если имя метки начинается
| |
| с цифры, то метка называется локальной, и ее действие распространяется
| |
| только между обычными метками, поэтому имена локальных меток в
| |
| программе могут повторяться. Двух одинаковых обычных меток в программе
| |
| быть не должно.
| |
| Комментарии должны начинаться с символа ";", их можно располагать
| |
| на отдельной строке или в конце строки оператора.
| |
| Поле "операция" содержит мнемокод машинной команды или
| |
| псевдокоманду ассемблера МИКРО.
| |
| Псевдокоманды начинаются с символа "." (точка). В таблице 18
| |
| рассмотрены основные псевдокоманды, применяемые в ассемблере МИКРО9.
| |
| В конце текста программы на ассемблере должна стоять псевдокоманда
| |
| "END".
| |
| Таблица 18. Основные псевдокоманды ассемблера МИКРО9
| |
| ┌────────┬──────────────────────────────────────────┬───────────────┐
| |
| │ формат │ выполняемые действия │ пример │
| |
| ╞════════╪══════════════════════════════════════════╪═══════════════╡
| |
| │ .+К │ резервируется К байт │ .+45 │
| |
| ├────────┼──────────────────────────────────────────┼───────────────┤
| |
| │ .#Е │ запись значения выражения Е (в слово) │ .#14 │
| |
| ├────────┼──────────────────────────────────────────┼───────────────┤
| |
| │ .@E │ получение смещения. По адресу этой псе- │ .@MET │
| |
| │ │ вдокоманды записывается число, равное │ │
| |
| │ │ разности адреса метки Е (Е - имя метки) │ │
| |
| │ │ и адреса самой псевдокоманды │ │
| |
| ├────────┼──────────────────────────────────────────┼───────────────┤
| |
| │ .Е │ здесь Е - символ "Е". Эта псевдокоманда │ │
| |
| │ │ обнуляет байт (если значение счетчика │ │
| |
| │ │ адресов нечетно) или слово (если значение│ │
| |
| │ │ счетчика адресов четно) │ │
| |
| ├────────┼──────────────────────────────────────────┼───────────────┤
| |
| │ .В:К │ Записывает значение выражения К │ .В:57 │
| |
| │ │ в текущий байт │ │
| |
| ├────────┼──────────────────────────────────────────┼───────────────┤
| |
| │ .А:... │ Запись произвольной строки символов "..."│ .А:Привет │
| |
| │ │ с текущего адреса │ │
| |
| └────────┴──────────────────────────────────────────┴───────────────┘
| |
| Поле "операнды" содержит информацию о местонахождении операндов,
| |
| участвующих в операции.
| |
| Поле "операция" отделяется от поля "операнды" хотя бы одним
| |
| пробелом. Если команда двухоперандная, то операнд источника отделяется
| |
| от операнда приемника запятой. Например:
| |
| | |
| MOV R1,R4
| |
| | |
| Ниже будут рассмотрены некоторые характерные для ассемблера примеры
| |
| программирования.
| |
| | |
| Пример 1: LF=12
| |
| KBD=177662
| |
| MOV #LF,R3 MOV #12,R3
| |
| MOV KBD,R0 MOV @#177662,R0
| |
| | |
| Программы слева и справа дадут одинаковый результат.
| |
| Строка программы, имеющая вид <имя> = <число>, называется
| |
| оператором прямого присваивания. Этот оператор похож на описание
| |
| констант в языках высокого уровня, и вводится для удобства обозначения
| |
| часто используемых констант или адресов (например, адресов системных
| |
| регистров, как в данном примере). В данной версии ассемблера МИКРО
| |
| есть ограничение: с помощью оператора присваивания можно работать
| |
| только с адресами в диапазоне от 0 до 777 и от 100000 до 177777, при
| |
| использовании таких имен в программе будет обеспечен абсолютный метод
| |
| адресации. Этим МИКРО отличается от ассемблера MACRO для ЭВМ ДВК и СМ,
| |
| где последнюю команду для получения абсолютной адресации следовало бы
| |
| записать как "MOV @#KBD,R0".
| |
| | |
| Пример 2:
| |
| Адрес Команда Текст на ассемблере
| |
| 6000: 000167 JMP VAR+2
| |
| 6002: 001004
| |
| ... ... ...
| |
| 7006: 005000 VAR: CLR R0
| |
| 7010: 010203 MOV R2,R3
| |
| | |
| Команда JMP передает управление на адрес, равный значению выражения
| |
| VAR+2=7006+2=7010.
| |
| Выражение в МИКРО9 - это имя метки и восьмеричное число,
| |
| соединенные знаком "+" или "-". В частном случае выражение - это имя
| |
| метки или восьмеричное число.
| |
| | |
| Пример 3:
| |
| Адрес Команда Текст на ассемблере
| |
| 1000: 012700 MOV #6,R0
| |
| 1002: 000006
| |
| 1004: 005060 A: CLRB TAB-1(R0)
| |
| 1006: 001777
| |
| 1010: 077003 SOB R0,A
| |
| . . .
| |
| 2000: TAB: .+6
| |
| | |
| В этом примере описан массив данных размером 6 байт, который
| |
| размещается с адреса 2000. Программа очищает (заполняет нулями) этот
| |
| масссив. Для работы с массивом используется индексный метод адресации.
| |
| Поскольку индекс - R0 меняется от 6 до 1, в качестве смещения
| |
| используется выражение "TAB-1"; при значении R0=1 команда
| |
| "CLRB TAB-1(R0)" очистит байт по адресу 2000).
| |
| | |
| Пример 4:
| |
| Адрес Команда Текст на ассемблере
| |
| 1000: 010701 MOV PC,R1
| |
| 1002: 062701 ADD (PC)+,R1
| |
| 1004: 000012 .@T+2
| |
| 1006: 005002 CLR R2
| |
| 1010: 104020 EMT 20
| |
| 1012: 000000 HALT
| |
| 1014: T: .A:Привет !
| |
| .E
| |
| | |
| Этот пример показывает, как на МИКРО можно писать перемещаемые
| |
| программы. Коды этой программы можно записать с любого адреса ОЗУ, и
| |
| она везде будет работать одинаково, так как адрес выводимой на дисплей
| |
| строки "Привет !" вычисляется относительно текущего значения PC после
| |
| выполнения команды "MOV PC,R1": 1002 + 12 = 1014, где .@T = 10 -
| |
| смещение от адреса этой псевдокоманды до начала текста (метки Т), а
| |
| еще 2 добавлено для учета самой команды "ADD (PC)+,R1".
| |
| А вот так предлагается организовать подпрограмму для вывода текста
| |
| в описании МИКРО#10S (программа также перемещаемая). Предлагаем
| |
| читателю самостоятельно разобраться в ее работе, напомним только, что
| |
| после вызова подпрограммы командой "JSR PC,..." в стеке (по @SP)
| |
| сохраняется адрес следующей команды (адрес возврата):
| |
| | |
| JSR PC,TEX ;вызов подпрограммы вывода текста и передача ей
| |
| .@T ;смещения до текста в качестве параметра
| |
| HALT ;продолжение основной программы
| |
| T: .A:Привет ! ;строка текста
| |
| .E ;нулевой байт в конце строки и выравнивание
| |
| ;адреса на границу слова
| |
| TEX: MOV @SP,R1 ;получение адреса псевдокоманды .@T
| |
| ADD @R1,R1 ;получение абсолютного адреса строки Т
| |
| CLR R2 ;вывод строки на дисплей
| |
| EMT 20 ;
| |
| ADD #2,@SP ;установить адрес возврата на следующую за .@T
| |
| RTS PC ;команду программы (в данном случае - HALT)
| |
| | |
| 5.3.2. Работа с системой МИКРО
| |
| | |
| Для получения готовой программы в машинных кодах необходимо
| |
| проделать следующие операции:
| |
| - набор исходного текста (текста программы на языке ассемблера) при
| |
| помощи редактора текста;
| |
| - трансляция (перевод) исходного текста программы в промежуточную
| |
| заготовку (объектный модуль) при помощи ассемблера (транслятора);
| |
| - компоновка (составление) из нескольких объектных модулей готовой к
| |
| выполнению программы в машинных кодах (загрузочного модуля ) при
| |
| помощи программы, называемой компоновщиком.
| |
| Все три программы: редактор текста, ассемблер и компоновщик
| |
| соеденены в одной программе МИКРО9, которая загружается и запускается
| |
| на выполнение с адреса 1000. Программа МИКРО9 может работать в одном
| |
| из четырех режимов:
| |
| - редактирование текста программы;
| |
| - трансляция (ассемблирование);
| |
| - компоновка;
| |
| - командный режим.
| |
| Сразу же после запуска МИКРО9 работает в командном режиме, о чем
| |
| свидетельствует символ "*". В командном режиме возможна подача одной
| |
| из следующих команд:
| |
| LO - Загрузка исходного текста с магнитной ленты (МЛ);
| |
| LF - Подстыковка текста с МЛ к тексту, находящемуся в памяти;
| |
| ST - Запись текста на МЛ;
| |
| SF - Запись на МЛ части текста от начала до строки, в которой
| |
| находился курсор при выходе из редактора текста;
| |
| SS - Запись на МЛ части текста от строки, в которой находился
| |
| курсор при выходе из редактора текста, до конца текста;
| |
| CO - трансляция текста с выводом его на экран;
| |
| CN - трансляция текста без вывода его на экран;
| |
| Примечание: после подачи команд CO и CN на экран
| |
| выводится вопрос "Е/N?", ответ на который
| |
| служит заданием действий, выполняемых
| |
| программой после возникновения ошибки:
| |
| E - прекратить трансляцию,
| |
| N - продолжить трансляцию;
| |
| SC - вход в редактор текста;
| |
| SA - запись на МЛ загрузочного модуля (готовой программы);
| |
| SL - запись на МЛ объектного модуля (промежуточной программы);
| |
| LI - компоновка объектного модуля, записанного на МЛ к модулю,
| |
| находящемуся в памяти (при этом получится программа,
| |
| загружаемая с адреса 1000 );
| |
| LA - компоновка объектных модулей, записанных на МЛ, с указанием
| |
| адреса последующей загрузки (эта команда применяется только
| |
| для головного модуля, остальные модули компонуются с помощью
| |
| команды "LI");
| |
| LL - компоновка объектного модуля сразу после трансляции (эта
| |
| команда применяется для программ, состоящих из одного
| |
| модуля; при этом получится программа, загружаемая с адреса
| |
| 1000);
| |
| LS - компоновка объектного модуля сразу после трансляции, с
| |
| указанием адреса последующей загрузки.
| |
| В некоторых версиях МИКРО предусмотрена команда запуска
| |
| скомпонованной программы "RU" или "GO".
| |
| | |
| 5.3.2.1. Работа в редакторе текста
| |
| | |
| Для набора текста программы на языке ассемблера в редакторе текста
| |
| используются следующие клавиши:
| |
| - клавиши перемещения курсора;
| |
| - клавиши "сдвижка в строке" и "раздвижка в строке";
| |
| - клавиша удаления части строки, расположенной справа от
| |
| курсора;
| |
| - "СУ/Т" - раздвижка строк программы;
| |
| - "ВС" - сдвижка строк программы;
| |
| - "СБР" - переход в конец текста;
| |
| - "СУ/Э" - переход в начало текста;
| |
| - "забой" - удаление символа, стоящего перед курсором;
| |
| - "СУ/Ъ" - выход из редактора;
| |
| - "КТ" - переход к строке с задаваемым номером.
| |
| Клавиши и особенности редакторов в различных версиях МИКРО
| |
| отражаются в соответствующих описаниях.
| |
| После изменения текста строки, а также для ввода новой строки
| |
| необходимо нажать клавишу "ВК".
| |
| В процессе редактирования в левом верхнем углу экрана отображается
| |
| количество оставшихся байт памяти, отведенных для текста.
| |
| | |
| 5.3.2.2. Ассемблирование
| |
| | |
| Если в исходном тексте программы на языке ассемблера нет ошибок, то
| |
| в результате трансляции образуется объектный модуль, иначе ассемблер
| |
| выдает сообщение об ошибках в виде:
| |
| | |
| ОШИБКА NN В СТР. ММММММ
| |
| где NN - номер ошибки;
| |
| ММММММ - восьмеричный номер строки текста.
| |
| Ниже приведены номера ошибок и их описание:
| |
| 1 - недопустимый символ в строке;
| |
| 2 - неверный оператор;
| |
| 3 - ошибка длины перехода по команде BR;
| |
| 4 - недопустимое имя метки;
| |
| 5 - недопустимый символ в поле операнда;
| |
| 6 - неверное число операндов;
| |
| 7 - нестандартное имя (там, где это необходимо);
| |
| 10 - неопределенное имя метки в операторе "SOB";
| |
| 11 - неверная псевдокоманда;
| |
| 12 - ошибка индексной адресации;
| |
| 20 - неправильная команда в командном режиме.
| |
| | |
| 5.3.2.3. Компоновка загрузочного модуля
| |
| | |
| Если исходный текст программы на языке ассемблера невозможно
| |
| набрать в один прием, то он набирается частями. Каждая часть исходного
| |
| текста при трансляции образует отдельный объектный модуль, затем все
| |
| объектные модули связываются (компонуются) компоновщиком в один
| |
| загрузочный модуль - в программу в машинных кодах, готовую к
| |
| выполнению.
| |
| Если загрузочный модуль компонуется из одного объектного модуля, то
| |
| компоновку можно произвести сразу же после трансляции исходного текста
| |
| подачей одной из следующих команд: LL или LS.
| |
| После успешной трансляции распечатывается таблица использованных в
| |
| модуле меток, при этом в инверсном виде распечатываются метки, которые
| |
| не определены в данном модуле, но используются в командах программы.
| |
| Это могут быть глобальные метки (определенные в другом модуле); тогда
| |
| необходима компоновка программы. Если Ваша программа состоит всего из
| |
| одного модуля, появление инверсных меток в таблице будет
| |
| свидетельствовать о Ваших опечатках.
| |
| Для компоновки нескольких модулей с магнитной ленты программу
| |
| МИКРО9 нужно привести в исходное состояние командой "RS".
| |
| | |
| 5.3.3. Пример программ на языке ассемблера
| |
| | |
| В первом примере приведен простейший генератор случайных чисел,
| |
| который можно использовать в игровых программах. Для начальной
| |
| установки генератора случайных чисел используется такой прием:
| |
| программа крутится в цикле, вызывая каждый раз генерацию нового
| |
| случайного числа, до тех пор, пока пользователь не нажмет любую
| |
| клавишу. Поскольку подгадать нажатие клавиши под нужное количество
| |
| циклов практически невозможно, то работа программы каждый раз будет
| |
| начинаться при новом значении случайного числа. Во время прохождения
| |
| очередного цикла можно производить какие-либо действия на экране (в
| |
| данном примере случайным образом рисуются точки случайного цвета).
| |
| | |
| ; Пример генератора случайных чисел
| |
| EMT 14 ;очищаем экран;
| |
| MOV #INE,R1 ;приведем экран в порядок;
| |
| CLR R2 ;
| |
| EMT 20 ;
| |
| MOV #100,@#177660 ;запретим прерывания от клавиатуры;
| |
| TST @#177662;снять готовность, если клавиша была нажата;
| |
| ; Начальная установка генератора случайных чисел
| |
| ING: MOV #2,R0 ;получаем случайный цвет (число от 0 до 2);
| |
| JSR PC,NRN
| |
| ADD #221,R0 ;получаем код символа установки цвета;
| |
| EMT 16 ;устанавливаем цвет;
| |
| MOV #377,R0 ;получаем случайное число от 0 до 377
| |
| JSR PC,NRN ;и используем его в качестве
| |
| MOV R0,R1 ;координаты X для вывода точки;
| |
| MOV #357,R0 ;получаем случайное число от 0 до 357
| |
| JSR PC,NRN ;и используем его в качестве
| |
| MOV R0,R2 ;координаты Y для вывода точки;
| |
| MOV #1,R0 ;рисуем точку;
| |
| EMT 30 ;
| |
| TSTB @#177660;если клавиша не нажата,
| |
| BPL ING ;продолжаем цикл;
| |
| TST @#177662;снять запрос на прерывание;
| |
| CLR @#177660;разрешить прерывания;
| |
| MOV RAN,R0 ;напечатать полученное
| |
| JSR PC,OUT ;случайное число;
| |
| HALT ;далее можно продолжать программу
| |
| ;----------------------------------------------------
| |
| ; Строка инициализации экрана (ставится режим 32 символа в строке,
| |
| ; убирается курсор и служебная строка)
| |
| INE: .B:233.B:232.B:224.B:236.B:221.B:0
| |
| ;----------------------------------------------------
| |
| ; Подпрограмма получения случайного целого числа
| |
| FRN: .#000327 ;это код команды "SWAB #RAN"
| |
| RAN: .#0 ;здесь будет целое случайное число
| |
| INCB RAN ;все эти операторы
| |
| ROLB FRN+3 ;предназначены
| |
| MM: ADD #0,RAN ;для получения
| |
| ADD #3337,MM+2 ;псевдослучайного числа
| |
| RTS PC
| |
| ;----------------------------------------------------
| |
| ; Получение в R0 случайного числа в диапазоне 0..R0
| |
| NRN: JSR PC,FRN ;получаем новое случайное число;
| |
| MOV R1,-(SP) ;сохраняем регистры в стеке;
| |
| MOV R2,-(SP)
| |
| MOV RAN,R1 ;отсекаем старшие разряды
| |
| MOV #100000,R2 ;случайного числа,
| |
| 1А: BIC R2,R1 ;
| |
| ASR R2 ;
| |
| CMP R1,R0 ;пока оно не войдет в заданный
| |
| BHI 1А ;диапазон;
| |
| MOV R1,R0 ;результат в R0;
| |
| MOV (SP)+,R2;восстанавливаем регистры;
| |
| MOV (SP)+,R1
| |
| RTS PC
| |
| ;----------------------------------------------------
| |
| ;Подпрограмма печати содержимого R0 в десятичной форме
| |
| OUT: TST R0 ;если число отрицательное,
| |
| BPL 1А ;то
| |
| NEG R0 ;изменить его знак на "+",
| |
| MOV R0,-(SP) ;сохранить R0 в стеке;
| |
| MOV #55,R0 ;вывести знак "-"
| |
| EMT 16 ;на экран;
| |
| MOV (SP)+,R0 ;восстановить из стека R0
| |
| 1А: JSR PC,OU1 ;вывести само число
| |
| RTS PC
| |
| ; Рекурсивная подпрограмма печати R0 в десятичной системе счисления
| |
| OU1: MOV R0,-(SP) ;делим в цикле содержимое стека
| |
| DEC R1 ;на 10 и получаем там количество единиц
| |
| CLR R0 ;(то есть младший десятичный разряд
| |
| 1А: INC R0 ;исходного содержимого R0),
| |
| SUB #12,@SP ;а в R0 получаем количество десятков
| |
| BGE 1А ;в исходном числе.
| |
| ADD #12,@SP ;
| |
| DEC R0 ;
| |
| BEQ 2А ;пока еще остаются в числе десятки
| |
| JSR PC,OU1 ;(т.е. старшие разряды), снова печатаем их,
| |
| ;для чего выполняем рекурсивный вызов
| |
| ;подпрограммы OU1
| |
| 2А: MOV (SP)+,R0 ;когда все число переведено и все
| |
| ;разряды сохранены в стеке,
| |
| ;вытаскиваем из стека очередной
| |
| ADD #60,R0 ;разряд и печатаем соответствующую
| |
| EMT 16 ;цифру
| |
| RTS PC
| |
| END
| |
| | |
| В этом примере для получения случайного числа используется простая
| |
| подпрограмма FRN. Псевдослучайная последовательность чисел, получаемая
| |
| с помощью этой подпрограммы, образует достаточно равномерное
| |
| распределение. Но все же определенная закономерность в этой
| |
| последовательности ощущается ("случайные" точки на экране более плотно
| |
| располагаются вдоль нескольких прямых). Случайное 16-разрядное число
| |
| генерируется в ячейке с адресом (меткой) RAN.
| |
| Для получения числа в заданном диапазоне используется подпрограмма
| |
| NRN. Сначала в R0 нужно записать верхнюю границу диапазона, потом
| |
| вызвать NRN, и в R0 будет находиться случайное положительное число в
| |
| из заданного диапазона.
| |
| Очень интересна подпрограмма печати числа в десятичной форме. Здесь
| |
| используется особый прием программирования - рекурсия. С помощью
| |
| рекурсивных процедур (то есть подпрограмм, которые вызывают сами себя)
| |
| можно вычислять факториал (классический пример из всех учебников),
| |
| закрашивать участки экрана и многое другое. В Фокале рекурсия
| |
| допустима, в Бейсике - нет.
| |
| Подпрограмма OU1 сохраняет в стеке количество единиц в печатаемом
| |
| числе, вызывает саму себя, чтобы напечатать старшие разряды числа,
| |
| после чего берет положенное в стек количество единиц и печатает
| |
| соответствующую цифру. Эта подпрограмма является достаточно
| |
| универсальной - Вы можете задать любую систему счисления, для чего
| |
| вместо константы 12 (10 в десятичной системе) записать любое другое
| |
| число, и программа будет печатать число в заданной системе счисления.
| |
| | |
| Следующий пример показывает, как можно сделать вывод изображения
| |
| (спрайта) на экран и управлять его движением.
| |
| Спрайтом называется прямоугольное изображение, его размеры обычно
| |
| кратны знакоместу экрана. Для редактирования спрайтов удобно
| |
| использовать графические редакторы, например, ГРЕД4 (О.Туйкин,
| |
| Д.Баранов). Этот редактор позволяет рисовать изображения цветными
| |
| точками и записывать их на магнитофон в виде файла следующего формата:
| |
| ширина спрайта в байтах (одно слово);
| |
| высота спрайта в точечных строках (одно слово);
| |
| далее по строкам пишется содержимое спрайта.
| |
| Предположим, мы нарисовали человечка (рис.25). Размер этого спрайта
| |
| совпадает с размером одного широкого знакоместа: 2 байта в ширину и 12
| |
| точечных строк в высоту (числа восьмеричные). Соответственно, ширина
| |
| спрайта в цветном режиме составляет 8 цветных точек. На рисунке
| |
| буквами "К" обозначены красные точки, "З" - зеленые.
| |
| | |
| . . З З К . . .
| |
| . . . К К . . .
| |
| . . . К . . . К
| |
| . К К К К К К .
| |
| К . . К К . . .
| |
| . . . К К . . .
| |
| . . К . . К . .
| |
| . . К . . К . .
| |
| . К К . . К К .
| |
| | |
| Рис.25. Пример рисования спрайта
| |
| | |
| Если теперь записать этот спрайт на магнитофон, то в файле будет
| |
| содержаться последовательность слов:
| |
| 2,12,1640,1700,140300,37774,1703,1700,1700,6060,6060,36074,
| |
| где первые два слова - ширина спрайта в байтах и высота его в строках.
| |
| Можно кодировать спрайт и вручную, заменяя каждую точку изображения
| |
| двумя битами и складывая их в слова, но это менее удобно.
| |
| Теперь приступим к написанию программы:
| |
| | |
| ;Пример вывода спрайта на экран и управления им с клавиатуры
| |
| EMT 14 ;инициализация экрана
| |
| ;---- вывод изображения (спрайта) на экран ----
| |
| BEG: MOV #MEN,R0 ;адрес спрайта;
| |
| MOV ADR,R1 ;адрес ОЗУ, куда будем выводить;
| |
| MOV (R0)+,R2 ;ширина спрайта в байтах;
| |
| MOV (R0)+,R3 ;высота спрайта в точечных строках;
| |
| A: MOV R2,R4 ;начало цикла по строкам;
| |
| MOV R1,R5 ;запоминаем адрес начала строки;
| |
| B: MOVB (R0)+,(R1)+ ;цикл вывода одной строки
| |
| SOB R4,B ;по байтам;
| |
| MOV R5,R1 ;восстанавливаем адрес начала строки;
| |
| ADD #100,R1 ;переходим к следующей строке;
| |
| SOB R3,A ;конец цикла по строкам.
| |
| ;---- временная задержка для замедления движения спрайта ----
| |
| MOV #4000,R3 ;число 4000 задает длительность задержки
| |
| W: SOB R3,W
| |
| ;---- очистка спрайта на экране -----
| |
| MOV #MEN,R0 ;адрес спрайта;
| |
| MOV ADR,R1 ;адрес ОЗУ, где будем стирать
| |
| MOV (R0)+,R2 ;ширина спрайта в байтах;
| |
| MOV (R0)+,R3 ;высота спрайта в точечных строках;
| |
| C: MOV R2,R4 ;далее все аналогично выводу спрайта,
| |
| MOV R1,R5
| |
| D: CLRB (R1)+ ;только здесь вместо пересылки -
| |
| SOB R4,D ;стирание
| |
| MOV R5,R1
| |
| ADD #100,R1
| |
| SOB R3,C
| |
| ;----------------------------------------------------
| |
| MOV @#177662,R0 ;код нажатой клавиши в регистр R0
| |
| CMP R0,#10 ;нажата клавиша "курсор влево"?
| |
| BNE RIT ;если нет, идти на метку RIT
| |
| MOV ADR,R2 ;иначе проверяется, не достигло
| |
| BIC #177700,R2 ;ли изображение левого края экрана
| |
| BEQ BEG ;если достигло, идти на метку BEG
| |
| DEC ADR ;иначе уменьшить на 1 адрес изображения
| |
| BR BEG ;и идти на метку BEG - переместить изо-
| |
| ;бражение левее на один байт
| |
| ;-----------------------------------------------------
| |
| RIT: CMP R0,#31 ;нажата клавиша "курсор вправо"?
| |
| BNE UP ;если нет, идти на метку UP
| |
| MOV ADR,R2 ;иначе проверяется,
| |
| BIC #177700,R2 ;достигло ли изображение
| |
| CMP #76,R2 ;правого края экрана
| |
| BEQ BEG ;если достигло, идти на метку BEG
| |
| INC ADR ;иначе увеличить адрес изображения на 1
| |
| BR BEG ;и идти на метку BEG - переместить изо-
| |
| ;бражение правее на один байт
| |
| ;------------------------------------------------------
| |
| UP: CMP R0,#32 ;нажата клавиша "курсор вверх"?
| |
| BNE DON ;если нет, идти на метку DON
| |
| CMP ADR,#42100 ;изображение достигло верхнего
| |
| ;края экрана?
| |
| BLO BEG ;если достигло, идти на метку BEG
| |
| SUB #200,ADR ;иначе адрес изображения уменьшить на 200
| |
| BR BEG ;и идти на метку BEG (переместить
| |
| ;изображение на две строки выше)
| |
| ;-----------------------------------------------------
| |
| DON: CMP R0,#33 ;нажата клавиша "курсор вниз"?
| |
| BNE BEG ;если нет, идти на метку BEG
| |
| CMP ADR,#76500 ;иначе проверяется достигло ли
| |
| ;изображение нижнего края экрана
| |
| BHI BEG ;если достигло, идти на метку BEG
| |
| ADD #200,ADR ;иначе адрес изображения увеличить на 200
| |
| BR BEG ;и идти на метку BEG (переместить
| |
| ;изображение на две строки ниже)
| |
| ;-----------------------------------------------------
| |
| ADR: .#56036 ;текущий адрес начала изображения
| |
| ;---- таблица изображения (спрайта) ----
| |
| MEN: .#2.#12.#1640.#1700.#140300.#37774.#1703.#1700.#1700
| |
| .#6060.#6060.#36074
| |
| END
| |
| | |
| В приведенной программе в переменной ADR (ячейке памяти, помеченной
| |
| меткой ADR) хранится адрес, по которому рисуется спрайт в экранном
| |
| ОЗУ. С этого адреса начинается вывод левого верхнего угла спрайта.
| |
| Начальное значение (56036) определяет, что в первый раз изображение
| |
| будет выведено около центра экрана.
| |
| Сначала спрайт выводится в экранное ОЗУ с заданного адреса, а
| |
| затем, после истечения некоторой задержки, стирается с экрана, и
| |
| программа анализирует код клавиши. Если нажата любая клавиша, кроме
| |
| стрелок управления курсором, переменная ADR не изменяется, и спрайт
| |
| вновь рисуется на прежнем месте. Если нажата стрелка, то ADR
| |
| изменяется, и спрайт будет в следующий раз нарисован уже в другом
| |
| месте экрана.
| |
| | |
| </pre>
| |
|
| |
|
| [[Категория:Программирование на БК-0010-01]] | | [[Категория:Программирование на БК-0010-01]] |