Использование макроопределений в языке ПЛ/М
Э. М. Пройдаков
Язык ПЛ/М [1–10] – это семейство машинно-ориентированных языков (ПЛ/М-80, ПЛ/М-86, ПЛ/М-286, ПЛ/М-386, ПЛ/М-51 и ПЛ/М-96) высокого уровня для программирования однокристальных ЭВМ, микропроцессорных контроллеров и систем. Цифры в названиях языков указывают на базовый тип поддерживаемого микропроцессора. Как правило, существует несколько реализаций каждого из перечисленных языков, включая кроссовый вариант. Языки семейства ПЛ/М имеют блочную структуру, строго типизированные данные и внешний набор библиотек ввода-вывода. При всеобщем увлечении языком Си следует отметить, что ПЛ/М проще, надежней, читабельней, лучше учитывает специфику программирования перечисленных выше систем и архитектурные особенности микропроцессоров, для которых он реализован. Перечислим операционные системы, в которых реализованы языки семейства ПЛ/М:
ОС | Язык |
---|---|
СР/М-80, МР/М-80, МИКРОС-80, МикроДОС | ПЛ/М-80 |
ISIS-II, ISIS-III, ДОС1800, ДОС1810 | ПЛ/М-80, ПЛ/М-86, ПЛ/М-51 |
RMX-86, ДОС1810, RMX-286 | ПЛ/М-86, ПЛ/М-286 |
СР/М-86, МИКРОС-86, МР/М-86, ССР/М-86 | ПЛ/М-86, ПЛ/М-80 |
VAX VMS | ПЛ/М-86, ПЛ/М-286, ПЛ/М-386 |
MSDOS, МДОС1810 | ПЛ/М-86, ПЛ/М-80, ПЛ/М-51 |
Макроопределение в языке ПЛ/М позволяет присваивать имя (идентификатор) произвольной строке символов и в исходном тексте программы писать его вместо этой строки.
С помощью макроопределений программист может создать себе некоторый диалект языка, обеспечивающий психологический микроклимат для работы. При умелом использовании макроопределений читаемость программ улучшается: четче виден творческий почерк и индивидуальность автора программы. Для программистов, работавших ранее на других языках, некоторый комфорт может быть создан аналогиями с помощью макроопределений [11].
Имя строке символов присваивается оператором DECLARE:
DECLARE (идентификатор) LITERALLY <строка>;
где < > – метасимволы, в реальных операторах не пишутся.
При трансляции программы компилятор всюду, где встретится идентификатор с атрибутом LITERALLY, заменяет его на строку, заданную после LITERALLY. В качестве строки символов может быть использован произвольный текст, не противоречащий синтаксису ПЛ/М.
Для удобства в первую очередь следует переопределить некоторые ключевые слова самого языка ПЛ/М и прежде всего само слово LITERALLY (что, кстати, всегда и делают программисты фирмы Интел, где язык ПЛ/М используется наиболее широко). Например, один из вариантов:
LIT – сокращение слова LITERALLY;
IS или AS для получения англочитаемого макроопределения:
DECLARE AS LITERALLY 'LITERALLY';
Так как ПЛ/М является языком с явно определяемыми типами переменных, определений в программе пишется достаточно много, поэтому целесообразно заменить ключевые слова DECLARE и PROCEDURE на принятые для них сокращения:
DECLARE DCL AS 'DECLARE';
DCL PROC AS 'PROCEDURE';
Как видно из этих макроопределений, объявленный идентификатор можно сразу использовать в следующем макроопределении или операторе языка. Имеется тенденция к применению следующих макроопределений.
DCL EXT AS 'EXTERNAL',
REPEAT AS 'DO WHILE',
FOREVER AS 'WHILE 1',
PUBLIC AS 'COMMON',
THENN AS 'THEN DO',
ELLSE AS 'END; ELSE DO;',
ELSIF AS 'END; ELSE IF',
WORD AS 'ADDRESS',
DWORD AS '(2) WORD';
Предлагаемый далее набор макроопределений вводит в язык ПЛ/М несколько типов данных, которые в нем отсутствовали.
1. Логические данные. Они представлены в памяти одним байтом на каждую переменную или элементом одномерного логического массива и принимают значения 0FFH для состояния "истина> и 00Н – для состояния "ложь":
DCL BOOLEAN AS 'BYTE',
TRUE AS '0FFH',
FALSE AS 'NOT TRUE';
Эти макроопределения позволяют записывать операторы вида
DCL LEVEL$FLAS BOOLEAN;
. . .
LEVEL$FLAS=TRUE;
2. Строковые данные. Строки символов – важный объект в языке программирования. Однако в языке ПЛ/М первоначально стандарта на представление строк не было, он появился начиная с языка ПЛ/М-86. В ПЛ/М-80 каждый программист имеет возможность создать собственный набор процедур для работы со строками. Следующее макроопределение делает более удобным объявление строки символов:
DCL STRING AS '(*) ВУТЕ INITIAL'
Это позволяет вместо объявления
DECLARE FN$MSG(*) BYTE INITIAL (CR, LF, 'ИМЯ ФАЙЛА: ');
записать более короткое и ясное
DCL FN$MSG STRING (CR, LF, 'ИМЯ ФАЙЛА: ');
(Психологические аспекты выбора имен команд рассматриваются в статье [11].)
Для неизменяемых строк текста тип определяется как
DCL TEXT AS '(*) BYTE DATA';
Для работы с символами по аналогии с языком Си можно определить тип CHAR:
DCL CHAR AS 'BYTE';
3. Указатели. В ПЛ/М-80 этот тип данных неявно вводится при использовании дот-операции; в языке ПЛ/М-86 он встроенный и определяется с помощью атрибута POINTER в операторе DECLARE. В ПЛ/М-80 указатели можно ввести для улучшения читаемости программ:
DCL POINTER AS 'ADDRESS';
Кроме того, к именам переменных, используемых в качестве указателей, рекомендуется добавлять окончания $Р или $PTR, например; CHR$PTR.
Константы в программе можно определить с помощью
DCL CONST AS 'BYTE DATA';
(ИЛИ 'WORD DATA')
Язык ПЛ/М имеет блочную структуру и, как это принято в современных языках, только один тип скобки, закрывающей блок (END;). Поэтому при написании программ с большим числом вложенных блоков, даже при аккуратном соблюдении отступов, не всегда сразу видно, какой "END;" к какому блоку относится. Типична такая запись:
END;
END;
END;
Если именовать закрывающую скобку блока в соответствии с его типом, то читаемость программы заметно улучшится:
ENDDO AS 'END',
ENDCASE AS 'END',
ENDIF AS 'END',
ENDPROC AS 'END',
ENDREPEAT AS 'END',
ENDWHILE AS 'END';
Вышеизложенное в полной мере относится и к используемым в языке Си фигурным скобкам, которые к тому же на многих 8-разрядных ПЭВМ отображаются буквами Ш и Щ.
При определении имен констант, портов ввода-вывода и управляющих символов употребление макроопределений аналогично по своей сущности псевдокоманде EQU в Макроассемблере:
DCL SUM AS 'A+B+С';
DCL LINE as '-*-*-*-*-*-*-*-*';
DCL BUFFER AS 'STRUCTURE
(LEN BYTE,
ACTUAL$LEN BYTE,
SECTOR(128) CHAR)';
Набор объявлений, облегчающий работу с управляющими символами и часто встречающимися константами:
DCL CTRL$C AS '03H',
CTRL$Q OS '11Н',
CTRL$S AS '13H',
CTRL$X AS '18H';
DCL CR AS '0DН', /* ВОЗВРАТ КАРЕТКИ */
LF AS '0AH', /* ПЕРЕВОД СТРОКИ */
CRLF AS 'CR,LF', /* НОВАЯ СТРОКА */
BELL AS '07H', /* 3ВOHOK */
TAB AS '09Н', /* ТАБУЛЯЦИЯ */
BACKSPACE AS '0BH',
SPACE AS '20H', /* ПРОБЕЛ */
NULL AS '00Н',
NIL AS '0000Н', /* НЕСУЩЕСТВУЮЩИЙ УКАЗАТЕЛЬ */
MAXINT AS '0FFFFH'; /* МАКСИМАЛЬНОЕ ЧИСЛО */
и т. д. в зависимости от задачи, устройств и других обстоятельств.
Посредством макроопределений удобно записывать константы для программирования БИС, например для последовательного интерфейса КР580ВВ51А;
DCL BUF$SIZE AS '4096',
DATA$51$PORT AS '0F6H',
STAT$51$PORT AS '0F7H',
WRT$STATUS AS '0000$0001B',
RD$STATUS AS '10B',
RESET$51 AS '0100$0000В',
MODE$SET AS '1100$1110B',
CMD$51 AS '0011$0101B';
Пример записи процедуры с использованием введенных в статье макроопределений:
/* ЭТА ПРОЦЕДУРА ВЫВОДИТ НА ЭКРАН СООБЩЕНИЕ, ПРИЗНАКОМ КОНЦА КОТОРОГО ЯВЛЯЕТСЯ 00. */
PRINT: PROC (PTR);
DCL PTR POINTER, CHR BASED PTR CHAR;
REPEAT CHR<>NULL;
CALL CO(CHR);
PTR=PTR+l;
ENDREPEAT;
ENDPROC PRINT;
Длина макроопределений (до 255 символов) позволяет использовать их и при определении структур. Кроме того, макроопределения могут быть вложенными (глубина вложенности не ограничена).
Все необходимые макроопределения рекомендуется сформировать в одном или нескольких файлах (обычно расширение имени файла. LIT) и включать их в исходный текст программы с помощью директивы
$INCLUDE "имя–файла",
где имя файла – имя файла с макроопределениями.
Более широкие возможности конструирования диалектов над языком ПЛ/М появляются при создании отдельных препроцессоров, например с использованием универсального макропроцессора STAGE2.
Макроопределения не влияют на объем объектного кода программы. Для улучшения качества объектного кода рекомендуется изучить получаемые листинги трансляции, в которых при задании директивы $CODE видно, как реализуется тот или иной оператор. Проведенный автором подсчет коэффициента расширения для языка ПЛ/М-80 (версия 3.1) показал, что в среднем для системных программ один исполняемый оператор языка ПЛ/М-80 расширяется в шесть машинных команд. Это означает, что программа на ПЛ/М пишется от трех до шести раз быстрее, чем на ассемблере.
Для ряда программ (например, технологических) существенно программирование их на языке проблемной области пользователя. С помощью макроопределений можно заменить ключевые слова ПЛ/М на русские и использовать русские идентификаторы так. чтобы они несли смысловую нагрузку в рамках решаемой задачи. При этом нет потери пресловутой совместимости.
В число других важных вопросов техники программирования входят структура объектного файла, стыковка программ на разных языках и мониторы микроЭВМ. Эти вопросы будут освещены в подготавливаемых статьях.
Литература
- Мыскин А. В., Торгашов В. А. Инструкция по программированию на PL/M-80. – Л.: ЛНИВЦ АН СССР, 1980 – 63 с.
- Каган Б. М., Сташин В. В. Микропроцессоры в цифровых системах. – М.: Энергия, 1979 – 193 с.
- Микропроцессоры: системы программирования и отладки // Под ред. В. А. Мясникова, М. Б. Игнатьева. – М.: Энергоатомиздат, 1985 – 272 с.
- Гребенщиков Л. К., Летник Л. А. Программирование микропроцессорных систем на языке ПЛ/М. – М.: Финансы и статистика, 1986 – 160 с.
- McCrachen D. D. A Guide to PL/M Programming for Microcomputer Application. – SI, Addison-Wesley, 1978 –262 p.
- PL/M-80 Programming Manual. – Intel Corp. – USA, 1977 – 106 p.
- PL/M-86 Programming Manual. – Intel Corp., 980466A – USA, 1978 – 110 p.
- PL/M-86 User's Guide. – Intel Corp., 121636 – USA, 1982 – 250 p.
- PL/M-51 User's Guide. – Intel Corp., 121966 – USA, 1983 – 150 p.
- PL/M-286 User's Guide. – Intel Corp., 121945 – USA, 1982 – 239 p.
- Кертис Б., Солоуэй Э. М., Брукс Р. Е. и др. Психология программных систем // ТИИЭР – 1986 – № 8 – Т. 74 – С. 42–60.
Статья опубликована в журнале "Микропроцессорные средства и системы" №6, 1988 г., стр. 25.
Перепечатывается с разрешения автора.