Описание
компьютера Радио-86РК
|
Журнал
РАДИО
|
ЯЗЫК ФОРТ ДЛЯ “РАДИО-86РК”
Н. ШИХОВ, г Козьмодемьянск, Республика Марий-Эл.
ФОРТ — один из самых молодых языков программирования, однако благодаря таким своим достоинствам как быстрота освоения (простейшие приемы программирования на нем можно освоить буквально за несколько минут) и высокая производительность, он уже приобрел во всем мире необычайную популярность. Сегодня мы предлагаем читателям версию этого языка для радиолюбительского компьютера “Радио-86РК".
"УМИРАЮТ" ЛИ ВОСЬМИРАЗРЯДНЫЕ МИКРОПРОЦЕССОРЫ
По миру победно шествуют мощные микропроцессоры I80486, MC68030 MICRO VAX, на смену им идут PENTIUM, МС680ХХ и новый сверхмощный 64 разрядный Альфа чип фирмы DEC. Сегодня можно приобрести почти все, что только пожелаешь. Иногда кажется, что для простеньких восьмиразрядных компьютеров уже не осталось места под солнцем.
Однако это не так. В микропроцессорной технике есть место и для "слона" PENTIUM и для "муравья" I8085 и как это часто бывает, эффективность применения ЭВМ зависит не столько от мощности и совершенства микропроцессора, столько от скорости и стоимости ее внедрения в производство.
По последним двум показателям восьмиразрядные "персоналки” не имеют конкурентов. Они не только не "вымирают", а даже продолжают совершенствоваться. Например, микропроцессор К580ВМ1 программно и аппаратно совместимый с К580ВМ80 обладает в 2,5 раза более высокой производительностью и расширенной системой команд, в которую входят четырех и пятибайтные команды.
Восьмиразрядные микропроцессоры прочно обосновались в микроконтроллерах, управляющих несложными технологическими процессами в измерительной технике. Мощности восьмиразрядных ЭВМ с лихвой хватает для любых бытовых целей — от управления теплицей или инкубатором, до автоматического определения номера звонящего абонента. На любительской радиостанции компьютер выполнит любую рутинную работу — от ведения журнала до автоматического управления любым “железом" и даже если нужно проведет радиосвязь без участия оператора.
Во всем этом есть, однако одна, хорошо известная тонкость, компьютер выполняет лишь то, что заложено в него программой. А вот оснащенность программным обеспечением его качество и сервисные характеристики у восьмиразрядных машин неизмеримо ниже. Особенно сказывается дефицит простых быстродействующих компактных трансляторов основных языков программирования. Об этом и пойдет речь далее.
Автор имеет опыт программирования на языках БЕЙСИК, ПАСКАЛЬ, ФОРТ и АССЕМБЛЕР для восьми и шестнадцатиразрядных процессоров. Из экономии времени и места не будем сравнивать эти языки (тот, кто с ними работал хорошо знает их достоинства и недостатки) а сразу выделим один из них. Он доводит мощность восьмиразрядных ПЭВМ до уровня шестнадцатиразрядных, позволяет выжать из машины все, на что она способна; обеспечивает доступ не только к любому байту, но и биту, находящемуся в любой ячейке памяти или регистре ЭВМ; занимает в памяти наименьший объем и в то же время обеспечивает наиболее быструю компиляцию программы в коды процессора за один проход текста программы; программирование на нем в 5 раз быстрее, чем на БЕЙСИКе, в 15 раз быстрее, чем на ПАСКАЛе и в 50 раз быстрее, чем на АССЕМБЛЕРе.
ЭТОТ ЯЗЫК – ФОРТ.
ФОРТ — один из самых молодых языков программирования, однако благодаря быстроте освоения и высокой производительности программирования он уже приобрел во всем мире необычайную популярность среди ценителей красоты в этом сложном, но увлекательном искусстве. В России и за ее пределами имеется немало версии языка, но публикаций на эту тему мало.
Простейшие приемы программирования на ФОРТе можно освоить буквально за несколько минут. В отличие, например, от АССЕМБЛЕРа программирование на ФОРТе напоминает скорее игру, нежели кропотливый труд алхимика, хотя в результате можно получить программу не уступающую АССЕМБЛЕРНОЙ.
Особенностями языка ФОРТ являются обратная польская (постфиксная) запись арифметических и логических операций, а также широкое использование стеков, привычное для многочисленных владельцев программируемых калькуляторов. Но главная особенность ФОРТа в том, что его каждый пишет сам для себя, а минимальный словарь резидентной части нужно рассматривать лишь как начальный капитал, дающий большой процент годовых, причем ФОРТ как губка впитывает и усваивает лексикон и характер своего хозяина, приближаясь к обычному разговорному языку.
Предлагаемая читателям версия языка ФОРТ не единственная, адаптированная для "Радио 86РК". У автора имеется версия ФОРТ системы разработанная в НИИСЧЕТМАШ ЛГУ. Она выполнена в строгом соответствии со стандартом FORTH 83, имеет объем 14 Кбайт и словарь примерно из 500 слов. По мнению автора, владельцами "Радио 86РК" эта программа использоваться на практике не может. Ее словарь перегружен промежуточными словами, не используемыми в прикладных программах, есть слова с одинаковыми функциями. Достоинствами этой версии являются, ее соответствие стандарту, и наличие встроенного ФОРТ АССЕМБЛЕРа. Стандартный строчный редактор ничего кроме сожаления не вызывает.
Дамп предлагаемой версии языка ФОРТ для компьютера "Радио 86РК" приведен в табл. 1, блочные контрольные суммы — в табл. 2. Версия работает с удобным и привычным редактором "МИКРОН “. Отсутствие ФОРТ АССЕМБЛЕРа, компенсируется возможностью вставлять в программу машинные коды или использовать АССЕМБЛЕР из пакета "МИКРОН".
Словарь включает в себя наиболее употребительные слова из распространенных версий ФОРТа, и позволяет писать программы обработки текстов, строк символов, битов байтов и шестнадцатиразрядных слов по алгоритмам любой степени сложности. Он наиболее приспособлен для разработки управляющих игровых и системных программ. Некоторые слова работают несколько иначе, чем в стандартных версиях.
Внутренняя структура словаря нестандартна, но именно благодаря такой структуре удалось достичь компактности и высокого быстродействия предлагаемой реализации, а также простоты генерации расширения системы модулями, написанными на АССЕМБЛЕРе.
Программирование на ФОРТе можно изучить по литературе [1—3]. После этого рекомендуется разобраться в прилагаемой демонстрационной программе (табл. 3) и тут же провести первые пусть не всегда удачные, но поучительные эксперименты. Далее будем предполагать, что читателю уже известны “азы" программирования на ФОРТе.
ОСОБЕННОСТИ ПРЕДЛАГАЕМОЙ ВЕРСИИ.
Большинство слов резидентной части словаря от COLD до (точки) работают, так же как и в стандартном FORTH 83, поэтому есть смысл описать только отличия от этого стандарта.
Итак, несколько иначе
работают:
‘
TYPE
QUERY
INTERPRET
"
Отсутствуют слова DO LOOP и +LOOP.
Слово ' (апостроф) в отличии от стандартного в FORT-83 не является словом немедленного исполнения, но если это необходимо, его можно сделать таким командой IMMEDIAT.
Слово 'возвращает значение адреса исполняемой части слова (поля кода, CFA), стоящего после него, или -1, если слово не найдено. Коренное же отличие работы этого слова в том, что оно производит поиск слов в словаре от начала к концу, что связано с особенностями реализации, которая, прежде всего, оптимизирована по быстродействию. Повторное описание слов с уже имеющимся именем бессмысленно, так как это слово никогда не будет найдено, пока не будет переименовано более раннее определение.
Слово TYPE берет из стека адрес строки, имеющей в конце либо нулевой байт, либо байт с кодом более 7FH, распечатывает эту строку и возвращает адрес байта ограничителя, стоящего в конце строки. Таким образом, это слово может распечатывать текст, порожденный не только в системе ФОРТ, но и другими компиляторами.
Слово QUERY берет из стека адрес буфера, и заносит в него символы с устройства, ввода пока не будет введен код <ВК>или CTRL+C. Так как это слово берет адрес буфера из стека то входной буфер можно расположить в любом месте ОЗУ. QUERY — это встроенный редактор системы ФОРТ. Весь порожденный этим словом текст является одной большой строкой, в которой допускаются любые печатные символы, в том числе <ПС>. Редактирование внутри QUERY возможно с использованием клавиш курсора <— и —>.
Слово INTERPRET берет из стека адрес буфера и интерпретирует текст из этого буфера, пока не встретит слово QUIT или два нулевых байта, которые заносятся QUERY при вводе кода <ВК>. Так как адрес текста берется из стека то можно интерпретировать программу, расположенную в любом месте ОЗУ или ПЗУ.
Слово “ (кавычки) берет из входного буфера символы расположенные после него и компилирует их на вершину кодофайла, (для начинающих мы несколько позднее дадим определение этого понятия) пока снова не встретит символ ". На этом символе компиляция заканчивается, а на вершину кодофайла компилируется байт-ограничитель, имеющий код более 7FH в младших семи битах которого хранится информация о длине строки. Символ " в конце строки не компилируется, а используется в качестве разделителя, т. е. очередное слово может быть записано после него без обязательного пробела, разделяющего слова в тексте программы.
И, наконец, слова DO LOOP и +LOOP. Они просто не нужны, так как в предлагаемой версии имеется только одна универсальная форма организации цикла со счетчиком:
: XX <ОПЕРАТОРЫ> КККК NNNN ММММ +DO <ОПЕРАТОРЫ ЦИКЛА> REPEAT <ОПЕРАТОРЫ>,
где КККК — конечное значение параметра цикла
NNNN — его начальное значение,
ММММ — приращение параметра цикла (шаг цикла).
Шаг может быть как положительным, так и отрицательным. Цикл выполняется последний раз, когда параметр цикла достигает конечного значения.
Если в программе имеются вложенные циклы со счетчиком, то доступ к параметру внутреннего цикла обеспечивает слово I, а к параметру внешнего цикла слово J
Все остальные слова выполняют абсолютно те же функции, что и в стандартном FORTH 83, и подробно описаны в [1]. Это короткое, но полное описание языка ФОРТ и первые 18 с. полностью относятся и к предлагаемой реализации.
НЕСКОЛЬКО СЛОВ О ЦИКЛАХ С УСЛОВИЕМ
Вместо: BEGIN <УСЛОВИЕ>WHILE
<ОПЕРАТОРЫ ЦИКЛА> REPEAT
Рекомендую: BEGIN <УСЛОВИЕ> IF<ОПЕРАТОРЫ ЦИКЛА> REPEAT
Вместо: BEGIN <УСЛОВИЕ> UNTEL
Рекомендую: BEGIN < УСЛОВИЕ> IF ELSE REPEAT
НЕМНОГО О НАЧАЛЬНОЙ СТАДИИ РАБОТЫ ПРОГРАММЫ.
Первое, что делает ФОРТ — заполняет некоторые ячейки ОЗУ константами, 10 байт — с адреса 806Н по 80FH — в том же порядке переносятся в ОЗУ, начиная с адреса 1040H: первые 3 байта — это команда JMP 0F803H на подпрограмму ввода символа с клавиатуры, следующие 3 байта - команда JMP 0F809H на подпрограмму вывода символа на экран, еще 2 байта — адрес поля связи последнего слова в словаре (фактически это адрес первого байта последнего слова в словаре). И, наконец, последние 2 байта — адрес первой свободной ячейки кодофайла. Этот же адрес записывается и в поле связи последнего слова в словаре (обычно он указывает на байт, следующий за последним байтом последнего слова в словаре). Если возникнет необходимость расширить ФОРТ систему словами, написанными на АССЕМБЛЕРе, эти два адреса необходимо будет скорректировать.
Затем инициируются стек возвратов (занесением в регистровую пару SP адреса 1040H) и стек параметров (занесением в пару НL адреса 103ЕН) автоматически компилируется содержимое текстового буфера, начиная с адреса 2100Н. Если стартовый файл находится по другому адресу, то его следует занести в ячейки с адресами 841Н и 842Н.
Стартовый файл должен содержать хотя бы одно слово QUIT <ПРОБЕЛ> или два нулевых байта (см. демонстрационную программу в табл. 3).
Для выхода в МОНИТОР достаточно нажать клавишу <F4> или ввести команду F86C EXECUT. Клавишу <F4> можно перепрограммировать, записав по адресам А59Н и А5АН другое значение адреса перехода.
Язык ФОРТ может работать без текстового редактора, однако гораздо удобнее его использовать с одним из текстовых редакторов, например, из пакета "МИКРОН". При этом отпадает проблема сохранения текстов программ. Еще лучше если обе эти программы "зашиты" в ROM-диск и загружаются одновременно. В статье описывается работа с версией адаптированной для персонального компьютера "Радио-86РК".
Предположим, что читатель уже ввел коды интерпретатора и редактора “МИКРОН” в свой компьютер и запустил редактор командой G0. Теперь следует проверить работоспособность системы. В редакторе необходимо набрать строку:
: EDIT 0 EXECUT, WORDS QUIT.
и нажатием клавиши <СТР> выйти в ФОРТ, аналогично выходу в АССЕМБЛЕР. На экране дисплея появится список доступных в данный момент слов (их можно называть командами или операторами в зависимости от вкуса) и символ >, приглашающий к вводу этих слов. Последним в словаре будет слово EDIT. Набрав его и нажав затем клавишу <ВК>, вы снова перейдете в текстовый редактор 'МИКРОН'. Если все получилось, как описано, вас можно поздравить с первым успехом, вы написали первую программу на языке ФОРТ. Дело в том, что в словаре не было слова EDIT, и вы только что описали его, используя слово EXECUT.
В языке ФОРТ всего три основных правила:
Изучение ФОРТА лучше всего построить на экспериментальной проверке работы всех слов базового словаря. Кроме них в языке имеются еще и числа, которые не должны выходить за пределы шестнадцати двоичных разрядов, причем старший разряд является знаковым.
Пожалуй, первое, что должен сделать программист — это установить систему счисления, для чисел, вводимых с клавиатуры и выводимых на дисплей. Командой , устанавливают шестнадцатиричную систему счисления (при "холодном" запуске эта система устанавливается автоматически), командой — привычную для всех десятичную систему. С этой команды и можно начать. Надо сказать, что числа и команды можно вводить как по одному, нажимая после ввода каждого клавишу <ВК>, таки группами. Буфер ввода с клавиатуры вмещает до 128 символов. Введенные символы можно редактировать перемещением курсора и перепечаткой символов, введенных с ошибкой между всеми вводимыми словами и числами должно быть не менее одного пробела. После нажатия клавиши <ВК>, все числа помещаются в стек, а все слова немедленно исполняются, причем большинство слов работает с арифметическим стеком, являющимся универсальным средством передачи, как числовых, так и логических операндов. Арифметическим стеком или стеком параметров в данной версии ФОРТа называется совокупность памяти и регистров процессора, обеспечивающая хранение двухбайтных чисел и безадресный доступ к верхнему элементу стека.
Кроме арифметического, в фОРТ-системах имеется еще и стек возвратов, но о нем разговор особый.
Логические операнды могут принимать значение либо , либо TRUE. Логическое значение (ложь) — шестнадцатиразрядное число, в котором все разряды равны нулю (т. е. 0), TRUE (истина) — любое шестнадцатиразрядное число, не равное 0.
Для распечатки (в текущей системе счисления) числа, лежащего на вершине стека, имеется слово . (точка).
Например:
1 2 3 . . . <ВК>
распечатает
3 2 1
1 2 3 . . 4 . <ВК>
распечатает:
3 2 4
Первое число лежит на самом дне стека, и мы его еще не сняли. Взять число из стека может слово line'DROP или . (точка), т. е. При наборе:
. <ВК>
распечатается: 1
Если же еще раз внести
. <ВК>
распечатается:
СТЕК ПУСТ
Это же сообщение мы получим при работе некорректно написанной программы, пытающейся извлечь число из пустого стека, кроме того, в этом случае произойдет аварийное прекращение работы программы, и выход в . Еще, более худшие результаты получим если будем помещать числа в стек и не будем их снимать стек “наедет” на рабочие ячейки интерпретатора и мы не получим никаких сообщений, а просто разрушим ФОРТ систему.
Следовательно, при программировании на ФОРТе, пользователь должен строго следить за всеми изменениями, происходящими на стеках (их два, но о втором — стеке возвратов — мы пока не говорим). Для надежной работы интерпретатора не следует помещать в стек более шестнадцати чисел к тому же большие объемы чисел и символов лучше хранить в виде массивов, а стек оставить только для сверхоперативных переменных, число которых обычно не превышает трех.
Для трех верхних элементов стека в словаре имеется несколько слов обеспечивающих быстрый доступ к любому из ЭТИХ чисел. Для уяснения их работы проведем несколько экспериментов.
Наберем:
1 2 DUP . . . <ВК>
получим:
2 2 1
Слово DUP положило в стек копию верхнего элемента.
Наберем:
1 2 3 DROP . . <BK>
получим:
2 1
Слово DROP уничтожило (безвозвратно) верхний элемент стека.
Наберем:
1 2 3 SWAP . . .<BK>
получим:
2 3 1
Слово SWAP поменяло местами два верхних элемента стека.
Коротко, это можно описать в виде таблицы, в левой части которой находится само слово, а в правой — вначале состояние стека до введения этого слова, а затем (после разделителя в виде стрелки) – его состояние после того, как это слово введено. Пустой стек можно обозначить прочерком. В крайней правой колонке удобно поместить комментарии. Составим такую таблицу для слов, оперирующих верхними элементами стека (табл. 4). Попробуйте, используя эти слова и уже известное слово (точка), убедиться в верности комментариев приведенных в правой части таблицы. Если простые операции с элементами стека уже наскучили, то можно перейти к более сложным экспериментам в области целочисленной арифметики (табл.8). Последнее слово в этой таблице кроме действий указанных в комментарии проверяет частное от деления на переполнение и если оно имеет более шестнадцати двоичных разрядов, то происходит аварийное прерывание программы и выход в QUIT. Результат умножения может быть и 32 разрядным.
Убедиться в правильности комментариев можно, так же как и в предыдущем случае, вводом чисел и слов из табл. 5, проверяя полученные результаты словом (точка). Для усложнения опытов можно вводить по несколько операторов сразу.
Например:
1 2 3 4 5 + + SWAP - . .<
получим:
10 1
Когда почувствуете что с арифметикой у вас все в порядке и обратная польская бесскобочная запись арифметических действии (когда сначала пишутся операнды, а затем операторы выполняющие арифметические действия) уже не вызывает затруднений можно перейти к освоению логических операций.
Так как логических операторов всего три, имеет смысл свести их в одну таблицу с операторами сравнения (табл. 6). Попробуйте (желательно в шестнадцатиричной системе счисления) произвести необходимые действия над числами, лежащими на стеке с помощью слов из табл. 6, проверяя полученные результаты словом (точка). Для примера приведем некоторые возможные результаты:
7 1 AND>
1
7 1 OR .<>
7
7 1 ХОR . <ВК>
6
7 1 > . <ВК>
-1
7 1 < . <ВК>
0
7 1 = .<ВК>
0
Если ваши результаты совпадают с приведенными и вы поняли, почему это происходит, то можно считать, что освоение работы интерпретатора закончено. Прежде чем перейти к наиболее трудной части приведем таблицу слов, которые часто употребляются при работе с интерпретатором (табл. 7).
Немного о самой процедуре интерпретации, которую производит слово. Вначале любое встретившееся слово, с помощью слова ‘ (апостроф), отыскивается в словаре и если оно найдено его адрес передается слову , которое тут же его исполняет. Если же, слово не найдено, то с помощью слова NUMBER оно преобразуется в число, которое кладется в стек, а если слово не является и числом, то интерпретация прекращается, печатается знак вопроса, распечатывается весь текст исходной программы, начиная с ошибочного слова, а затем — словарь системы, напоминая, что можно использовать только известные системе слова.
ПОДПРОГРАММНЫЙ ШИТЫЙ КОД.
В предыдущем разделе мы рассмотрели работу системы ФОРТ в режиме интерпретации программы, вводимой с клавиатуры или из входного файла. У читателя, возможно, возник вопрос, как интерпретатор находит слова в словаре системы? Дело в том, что все слова входящие в ФОРТ систему представляют собой единый список называемый шитым кодом. Занимаемое им адресное пространство, называется кодофайлом. В версии для “Радио 86РК”, применен предложенный автором подпрограммный шитый код, который мы и будем разбирать.
Для примера приведем распечатку дампа двух рядовых слов, например, и DECIMAL.
ADDR. LFA NFA CFA
0F89 0FA5 HEX 83 3E 10 32 4A 10 C9
0FA5 0FB5 DECIMAL 87 ЗЕ 0A 32 4A 10 C9
Как видим, слово HEX начинается не с имени, а с некоторого двухбайтного адреса, указывающего на начало слова DECIMAL, которое в свою очередь также начинается с двухбайтного адреса, указывающего на начало следующего за ним слова.
Будем называть адреса, с которых начинается каждая словарная статья полем связи, так как именно они, обеспечивают связь всех слов в словаре и позволяют, зная адрес первого и последнего слова, отыскать и все остальные. Заметим, что в описываемой версии, список слов связан от начала к концу. Обычно поле связи обозначают аббревиатурой. За следуют ASCII коды имени и один стоп-байт. Поле имени кратко называют NFA.
Стоп байт отличается от ASCII кода имени тем, что имеет установленный в 1 старший (восьмой) знаковый бит. В младших шести разрядах стоп-байта, указывается длина имени ASCII кодов), а в седьмом бите — признак немедленного исполнения (IMMEDIAT), о котором мы поговорим позже. У слова HEX признака IMMEDIAT нет, и стоп-байт имеет значение 83Н, а у слова DECIMAL - 87Н. Так как под имя отведено только шесть бит его длина не может превышать 63 символов. За NFA следует поле кодов , состоящее из машинных команд процессора. Заметим, что именно адрес , возвращает слово (апостроф). CFA слева HEX состоит из трех машинных команд которые на языке АССЕМБЛЕРа выглядят так:
MVI А, 10Н ;записать в аккумулятор число 16
SТА 104АН ;переписать его в ячейку с адресом 104АН
RET ;возврат через стек возвратов
Рабочая ячейка с адресом 104АН, хранит текущее основание системы счисления, которое используется словами NUMBER и . (точка).
Если необходимо установить восьмеричную систему счисления, то следует подать команду:
НЕХ 8 104А С!<ВК>
или ввести в словарь новое слово OCTAL. Как это сделать, мы узнаем из следующего раздела.
За полем CFA может находиться поле параметров PFA. У переменных оно состоит из одного или двух байт, а у массивов быть любого размера. У констант и других слов ФОРТ системы отсутствует, т. е. имеет нулевой размер, хотя командой N , можно создать такое поле у любого слова, описанного последним. Следует отметить, что в других версиях языка ФОРТ поле LFA обычно следует за NFA, а последнее не заканчивается стоп-байтом, а начинается с байта-счетчика. Такую конструкцию называют строкой со счетчиком. Автор данной версии отказался от строки со счетчиком, так как использование строки со стоп-байтом имеет некоторые преимущества и более распространено в других системных и прикладных программах. Расположение LFA в начале словарной статьи, также имеет преимущества при генерации и расширении языка подпрограммами, написанными на АССЕМБЛЕРе.
РАБОТА ЯЗЫКА В РЕЖИМЕ КОМПИЛЯЦИИ.
Как мы заметили работа с языком в режиме интерпретации, позволяет вводить с клавиатуры или из входного файла числа и слова, имеющиеся в словаре, но в отличие от других языков программирования ФОРТ не имеет фиксированного словарного запаса и открыт для пополнения списка слов самими пользователями. Попробуем проверить это на практике. Для начала опишем какое-нибудь простое слово, например, OCTAL. Для этого введем с клавиатуры следующую строку:
: OCTAL 8 [ HEX ] 104А ! ; WORDS “B”
После распечатки словаря мы увидим, что в нем появилось новое слово OCTAL, которым можно пользоваться так же, как словами HEX и DECIMAL.
Каким же образом новые слова включаются в словарь? Это делает слово : (двоеточие), которое генерирует в конце кодофайла LFA и NFA нового слова, причем в NFA оно заносит имя слова, стоящего после двоеточия (через пробел, разумеется). Затем интерпретатор переключается в режим компиляции, и число 8 не кладется в стек, а в кодофайл компилируются машинные команды, которые при исполнении слова OCTAL будут помещать в стек число 8, затем если была установлена десятичная система счисления, необходимо установить шестнадцатиричную (чтобы ввести число 104АН) для чего необходимо временно снова выйти в режим интерпретации. В подобных случаях помогает слово [, которое не компилируется, а немедленно исполняется, потому, что в стоп-байте имени этого слова, имеется установленный в 1 бит признака IMMEDIAT.
Словом HEX устанавливаем нужную систему счисления и снова переводим интерпретатор в режим компиляции словом ]. Все следующие за ним слова, если они не имеют признака IMMEDIAT, будут скомпилированы на вершину кодофайла в виде машинных команд. Все числа компилируются в виде двух трехбайтовых команд типа:
CFA (слова DUP)
LXI В, <число>, а все слова — в виде одной трехбайтовой командыCFA (слова)
И, наконец, слово ; (точка с запятой) скомпилирует команду RET, и вновь переведет компилятор в режим интерпретации. Таким образом, будет сформировано CFA слова (в данном случае — OCTAL). Надо сказать, что слово включается в словарь немедленно, после описания LFA и NFA словом : (двоеточие). Это сделано специально для написания сложных рекурсивных программ, когда слово немедленно может обратиться к самому себе правда программист должен позаботиться о том, чтобы глубина вложенных обращений не превышала 32, так как подстек возвратов отведено только 64 байта.
Итак, на примере слова OCTAL мы разобрали, как пополнить список слов. Это и есть программирование на языке ФОРТ, когда вы пополняете его словарь словами, которые затем можно использовать в описаниях других слов, пока, наконец, не опишете слово, которое и будет выполнять необходимые действия. Тогда можете сразу исполнить это слово, введя его имя и нажав клавишу “ВК”. Как видите, программа составляется снизу вверх, когда сначала пишутся мелкие фрагменты, а затем окончательное слово, собирающее их воедино. Это впрочем, не мешает конструировать программу или ее алгоритм и сверху вниз.
Для тренировки напишите слово, которое вводит, интерпретирует и распечатывает текст, расположенный по адресу 2100Н. Вот одно из возможных решений:
: ПРИМЕР [HEX]
2100 QUERY 2100 INTERPRET
2100 TYPE CR ."КОНЕЦ ТЕКСТА". ;
СТРУКТУРНОЕ ПРОГРАММИРОВАНИЕ.
Как и подобает любому солидному языку, а в этом он превзошел, пожалуй, и ПАСКАЛЬ, язык ФОРТ позволяет писать структурированные программы любой степени сложности, без использования меток. Хотя словарь ФОРТа не фиксирован и даже начинающий программист может описать слово, вводящее понятие метки, он быстро убедится, в полной бесполезности этого открытия, так как в базовом словаре, имеются все необходимые слова, для описания ветвлений, циклов с проверкой условия, как в начале, так и в конца цикла, а также циклов со счетчиком. Основным словом позволяющим реализовать упомянутые структуры, является слово IF.
Как и прежде, рассмотрим его работу на простом примере.
: ПРИМЕР1 KEY DUP [HEX] 20 =
IF "ПРОБЕЛ" DROP
ELSE ENIT
THEN ."-ЭТА КЛАВИША ИСПРАВНА";
Как работает это слово? Слово KEY ожидает нажатия клавиши и помещает в стек код символа введенного с терминала. Затем слово DUP кладет в стек число 20Н, а слово = сравнивает эти числа и возвращает в стек либо TRUE (т. е. -1) если эти числа равны, либо FALSE (т. е. 0) если они не равны. Слово IF берет логическое значение, оставленное словом =, и если оно имеет значение TRUE, то выполняются операторы, следующие за словом IF (см пример 1), если был введен код пробела 20Н, то будет напечатано слово "ПРОБЕЛ". Затем слово ELSE передаст управление на операторы стоящие после слова THEN. Если же слово IF возьмет из стека значение FALSE, то оно передаст управление на операторы стоящие после слова ELSE. Слово THEN не выполняет никаких действий, а лишь расставляет на этапе компиляции правильные адреса для ссылки вперед в слове ELSE или IF (если ELSE отсутствует). Конечно же, парность операторов IF THEN абсолютно необходима и хотя в данной версии она и не проверяется самим компилятором, программист должен сам строго следить за соблюдением этого правила. В общем, виде структуру слов с операторами ветвление можно описать примерно так:
полная альтернатива:После столь подробного описания операторов ветвления желательно поупражняться в написании слов с их использованием. Заметим, что все структурные операторы имеют признак IMMEDIAT и могут использоваться только в описаниях других слов в режиме компиляции. В режиме интерпретации они не выполняют того, о чем было сказано выше. На самом деле эти слова только компилируют на вершину кодофайла несколько машинных команд, которые будут исполняться, только при исполнении слова, внутри которого они скомпилированы. В табл. 8 приведен список слов, которые также используются только в режиме компиляции.
Для демонстрации работы операторов цикла приведем несколько примеров.
: ПРИМ2 BEGIN KEY DUP 20 = IFЭто слово циклически опрашивает клавиатуру и печатает ASCII коды нажатых клавиш, при нажатии клавиши с кодом 20H (пробел), цикл заканчивается. Следующее слово работает примерно так же, но цикл заканчивается при нажатии на клавишу управления с кодом < 20Н.
: ПРИМ3 BEGIN KEY DUP 19 > IF EMITСледующее слово сразу после написания поздравит вас три раза.
DECIMAL : HELLO 22 10 6
+DO СR .'ПОЗДРАВЛЯЮ '
REPEAT; HELLO <BK>
ПРОГРАММИРОВАНИЕВ МАШИННЫХ КОДАХ.
До этого мы использовали только примитивы базового словаря, но подпрограммный шитый код позволяет вставлять в описания слов непосредственные машинные команды. Например, слово S, включает команды PUSH H и РОP В и распечатывает содержимое арифметического стека без его изменения.
: S DUP .[HEX Е5 С, С1 С, ]107A -2 +DO|® . REPEAT;
или то же самое
: S DUP .[HEX C1E5 .] 107A -2
+DO |© .REPEAT;
Программирование в машинных кодах является обоюдоострым свойством данной реализации, поэтому, для того чтобы не нанести непоправимого вреда ФОРТ системе (особенно если в программе происходят обращения по абсолютным адресам) приведем распределение адресного пространства адреса рабочих ячеек интерпретатора и назначение регистров процессора (табл. 9 и 10). Как видим верхнее число лежащее в стеке, на самом деле находится в регистровой паре ВС, чем и объясняется высокая скорость работы ФОРТ системы с вершиной стека (вспомните S). Слово DUP делает копию содержимого регистровой пары ВС примерно так
MOV M, В
DCX H
MOV M, C
DCX H
а слово DROP снимает число с вершины
INX H
MOV C,M
INX H
MOV B,M
Регистровыми парами PSW и DE пользуются почти все слова базового словаря, поэтому сохранность информации в этих регистрах не гарантируется.
Для упражнения попробуйте написать в машинных кодах слова повторяющие функции слов DUP и DROP. Следует избегать повторного использования слов, так как в данной версии их поиск производится сначала словаря, и исполняться будет слово, написанное раньше. В версиях языка, где список связан от конца к началу, повторное описание слова делает недоступным более раннее описание. В заключение приведем текст небольшой вирусной программы, которая, будучи один раз исполненной, перехватывает вектор вывода на дисплеи и обрабатывает код 09Н как команду горизонтальной табуляции. Для ее написания потребовалось всего несколько минут. Читателю предлагается обратить внимание на действие слов ограниченных словами [ и ]. И расшифровать их смысл.
CREAT CUR 0 ,
: TAB DUP TAB [ 01 HERE 3 C!] 1044 < DUP 9 =
IF 20
BEGIN
F809 EXECUT
CUR @ 1 + DUP CUR ! 7 AND
IF REPEAT DROP
ELSE
DUP 0D =
IF 0 CUR !
ELSE CUR ® 1 + CUR !
THEN F809 EXECUT
THEN;
Как видим написание вируса не такое уж и сложное дело. Но вряд ли стоит этим заниматься. Гораздо полезнее написать дельную программу. Вручая читателям свой труд, автор надеется, что именно этому они посвятят свое время и безграничную фантазию.
ПЕРЕМЕННЫЕ
В предыдущем примере мы использовали слово CUR, которое описано не через двоеточие, а словом CREAT. Что это за слово? Это — переменная. Переменными в языке ФОРТ называют слова, оставляющие на вершине стека адрес этой переменной (точнее адрес PFA в котором и хранится информация). Переменные могут быть одно и двухбайтными и образуются следующим образом:
однобайтные переменные
CREAT <ИМЯ ПЕРЕМЕННОЙ> 1 АLLOТ
или
CREAT <ИМЯ ПЕРЕМЕННОЙ> N С
Двухбайтные переменные
CREAT <ИМЯ ГЕРЕМЕННОЙ> 2 ALLOT
или
CREAT <ИМЯ ПЕРЕМЕННОЙ> N В
последних примерах переменной еще и присваивается начальное значение N. Доступ к переменным обеспечивают слова:
С! — запись байта из стека в переменнуюПопробуйте практически ознакомиться с переменными, так как личный опыт, к сожалению, ничем заменить нельзя.
МАССИВЫ.
Массивы — более общий случай переменных и отличаются от последних только большим размером. Например, команда
CREAT ARR3 0 0 0
создает массив из трех слов (т. е. Шесть байт), Особый интерес представляют
массивы, заполненные литерами. Попробуем создать такой массив командой:
СREАТ ARR$ “МАССИВ, ЗАПОЛНЕННЫЙ ТЕКСТОМ”
Попробуйте распечатать этот массив командой
ARR$ TYPE CR.
Слово TYPE распечатает текст, записанный в массив, и вернет, адрес стоп-байта записанного в конце массива словом “ (кавычки). Так как в стоп-байте семь бит несут информацию о длине массива, то не рекомендуется записывать в массив более 128 символов (хотя этим правилом иногда можно пренебречь). Эти же рекомендации относятся и к слову.”, которое пользуется услугами слова ”.
КОНСТАНТЫ
Константы в данной версии языка проще всего описывать, так же как и другие ФОРТ слова, через двоеточие. Например: TRUE –1; : FALSE 0; и так далее.
Но иногда необходимо создать константу со значением, взятым из стека. В этом случае можно поступить двояко;
Одно из возможных решений — слово CONST:
: CONST CREAT HERE 3 - ! ;
Обращение к этому слову имеет вид:
<ЗНАЧЕНИЕ> CONST <ИМЯ КОНСТАНТЫ>
Например:
1 CONST TRUE 0 CONST FALSE
РАСШИРЕНИЕ системы ФОРТ.
Конечно, расширение языка ФОРТ происходит и без вашего желания, хотя и не без вашего участия. Чтобы не изобретать велосипед старайтесь больше читать и использовать большее число слов уже достаточно устоявшихся или стандартизованных в других версиях. Это облегчит чтение ваших программ и позволит использовать программное обеспечение, написанное другими.
Начать легче всего с включения в ФОРТ систему стандартных подпрограмм МОНИТОРа и программ или подпрограмм написанных на АССЕМБЛЕРе. Для примера опишем процедуры ввода кода нажатой клавиши и опроса состояния клавиатуры:
: ?KEY 0 F81B EXECUT [4F С,];
Подобным же образом используя вставки в машинных кодах можно описать обращения
к любым программам и подпрограммам (например, так подключен редактор МИКРОН)/
Следует только позаботиться о стандартной передаче параметров через арифметический
стек, т. е. регистровую пару ВС и область памяти, адресуемую парой HL. Следует
также позаботиться и о том, чтобы внешние программы не нарушали работы стеков.
Исходные тексты программ написанных на АССЕМБЛЕРе можно включить в ФОРТ систему
и другим способом, используя тот факт, что область кодофайла пользователя, и
область трансляции АССЕМБЛЕРа МИКРОН расположены в одном и том же месте ОЗУ
начиная с адреса 1100Н. Снабдите все ваши подпрограммы заголовком аналогичным
полям LFA и NFA других слов ФОРТ-системы.
На ассемблере это выглядит так:
Загрузите АССЕМБЛЕР "МИКРОН" откомпилируйте программу, а затем, загрузив в ФОРТ, занесите в ячейки памяти по адресу 80СН адрес LFA последнего слова, а по адресу 80ЕН — слово, записанное по этому адресу, т. е. @PFA (см. выше). Запустив или перезапустив ФОРТ командой COLD, вы включите описанное слово в ФОРТ систему. Подобным образом можно унифицировать и включить в систему любую программу, написанную на АССЕМБЛЕРе. Еще один способ позволяет написать программу, которая может использоваться и без ФОРТа. Введите команды:
HEX 7400 HERE - ALLOT
2F3E, C23D, 7402, 0021,
ЗЕ21, CD08, F806, 00FA,
7774, С323, 7409,
После этого по адресу 7400Н будут записаны коды программы, которую можно запустить командой 7400 EXECUT или из МОНИТОРа командой G7400 <ВК>. Не вдаваясь в подробности, отметим, что эта программа позволяет вводить с кассеты тексты, записанные в формате редактора "МИКРОН” не только с начала, но и с любого места даже с середины. На этом описание работы с ФОРТом можно закончить. Остается только добавить, что после того, как написано и отлажено какое либо слово в пультовом режиме желательно командой 0 EXECUT выйти в редактор, и увековечить находку в виде текста который затем будет автоматически исполняться после входа в ФОРТ систему или после "холодного" старта словом COLD.
Желаю успехов.
ЛИТЕРАТУРА
1 Бураго А. Ю., Кириллин В. А., Роменовский И. В., ФОРТ — язык для микропроцессоров
— Л. Знания 1989.
2 Семенов Ю. А., Программирование на языке ФОРТ. – М. Радио и связь 1991.
3 Библиотека информационной технологии Вып. 2. Под ред. Г. Р. Громова — М. Инфоарт1991.
Отсканировано с журнала Радио №7, №8 и №10 1995 год.
Отредактировано Лесных Ю. 2001 год.
Описание
компьютера Радио-86РК
|
Журнал
РАДИО
|