Парадигматическая характеристика ассемблера
Параметр
Конкретика
Эксплуатационная прагматика ЯП
Ассемблер – средство эффективного программирования при решении задач доступа к полному спектру возможностей оборудования
Регистры абстрактной машины
S C M
S – сумматор;
C – поток команд программы с указателем на текущую команду;
M – вектор памяти произвольного доступа.
Результат рассредоточен по ячейкам памяти
Категории команд абстрактной машины
- вычисления с результатом в сумматоре, для которых следующая команда расположена по соседству;
- изменение части состояния общей памяти, при котором следующая команда расположена по соседству;
- обработка текста программы без генерации нового кода;
- управление со своими правилами выбора следующей команды;
- команды «знают», где их операнды.
Реализационная прагматика
- перемещаемость. Код можно расположить по любому абсолютному адресу;
- листание страниц памяти;
- зависимость от данных;
- динамика размещения;
- объектный код;
- билистинг;
66
-
прокрутка и отладчик;
- реассемблирование.
Парадигматическая специфика
Классический язык императивного машинно-ориентированного программирования.
3.2. Стековая машина ForthДля машинно-ориентированных языков, таких как Forth [1], система вычислений распадается на подсистемы по величине обрабатываемого слова (16 и 32, возможно, 64). Основа работы с памятью – стек. Средства управления вычислениями обогащены средствами блокировки и кодирования программ, что позволяет повышать эффективность информационной обработки. Используется механизм замкнутых процедур с неявными – стековыми – параметрами. Стек реализован как указатель на текущий элемент в предположении, что перед ним по порядку расположены предшествующие элементы.
Программа – отдельный поток, использующий расширяемый словарь.
Принята постфиксная запись, удобная для стековой обработки данных.
Стек-ориентированная дисциплина обработки освобождает от необходимости в понятии «переменная», хотя оно при необходимости моделируется.
Программирование на Forth-е сопровождается систематической сверткой понятий, синтаксис применения которых созвучен польской записи. Можно сказать, что хорошая программа на Forth-е – это специализированная виртуальная машина, приспособленная к дальнейшему расширению по мере развития постановки задачи.
Интерпретатор языка Forth сортирует слова по принадлежности словарю:
– слова, не найденные в словаре, записываются в стек для предстоящей обработки;
– словарным словам, встроенным в интерпретатор, соответствует правило преобразования стека;
– возможно определение новых слов, запоминаемое в словаре (от «:» до «;»);
– за корректность воздействий на стек отвечает программа;
– результатом считается состояние стека при завершении программы.
67
Программа на языке Forth строится как последовательность слов, некоторые их которых включены в расширяемый словарь языка:
Forth: текст/словарь → стек: стек → стек'
: слово → словарь
Данные – это тоже слова. Логическое значение «истина» – 0.
Новые слова можно вводить в форме:
: имя опр;
Абстрактный синтаксис языка отличается от АС ассемблера допущением произвольного числа неявных аргументов определяемых команд:
S E C → S’ E’ C’
S – стек результатов, E – словарь, представленный как вектор строк,
C – поток слов, образующих программу.
Исполнение программы организовано как диалог над стеком. Каждая команда знает, что взять из стека, во что преобразовать для получения результата программы и какие результаты разместить в стеке.
Т аблица 16
Команды стековой машины языка Forth
SCS
Описание команды
Примечание
LDC
Засылка из программы в стек.
Операнды.
DROP
Сбросить из стека верхний элемент.
Манипуляции с фиксированным числом элементов стека.
DUP
Скопировать верхний элемент.
NIP
Сбросить предпоследний элемент стека.
OVER
Предпоследний элемент переставить наверх.
PICK
Выборка из стека элемента с указанным номером.
SWAP
Обмен местами двух верхних элементов.
TUCK
Копирование верхнего элемента под второй с сохранением.
DEPTH
Глубина стека.
68
PICK
Выборка из стека элемента с указанным номером.
Манипуляции с заданным числом элементов стека.
ROLL
Перестановка на заданную глубину элемента из стека.
?DUP
Скопировать ненулевой верхний элемент.
LDF
Загрузить в словарь определение.
Укрупнение действий.
AP
Применить словарное определение.
Укрупнение действий – это новые определения с неявными параметрами в стеке.
Т аблица 17
Спецификация команд стековой машины языка Forth
RS
RS
Примечание
s e (LDC X . c)
(X . s) e c
Подготовка стека к предстоящим операциям.
N – длина стека
(X . s) e (DROP . c)
→ s e c
(X . s) e (DUP . c)
→ (X X . s) e c
(X2 X1. s) e (NIP . c)
→ (X1 . s) e c
(X2 X1. s) e (OVER . c)
→ (X2 X1 X2 . s) e c
(XN ... X0 N . s) e (PICK . c)
→ (XN ... X0 XN . s) e c
(XN ... X0 N. s) e (ROLL . c)
→ (XN-1 ... X0 XN . s) e c
(X3 X2 X1. s) e (ROT . c)
→ (X2 X1 X3 . s) e c
(X2 X1. s) e (SWAP . c)
→ (X1 X2 . s) e c
(X2 X1. s) e (TUCK . c)
→ (X1 X2 X1 . s) e c s (DEPTH . c)
→ (N . s) e c
(0 . s) e (?DUP . c)
→ (0 . s) e c
(X . s) e ( ?DUP. c)
→ (X X . s) e c
(NF . s) e (LDF F “;” . c)
→ s (e|e[NF]=F) c
Пополнение словаря.
(NF . s) e (AP . c)
→ s e (e[NF] . c)
Применение словарного определения.
Система программирования для языка Forth содержит пару
«интерпретатор – компилятор», причем техника компиляции весьма эффективна. Система использует единый порядок представления данных и команд в программе это последовательности слов. Данные располагают перед операциями по их обработке. Операция – это известное системе
69
слово. Данные просто загружаются на стек, из которого операция берет их в соответствии с числом ее параметров.
Интерпретирующий автомат для языка Forth по сложности сравним с автоматом для ассемблера. Основные различия таковы:
– словарь Forth-а
хранит строки произвольной длины, а таблица меток ассемблера хранит адреса фиксированного размера;
– вместо запоминания адреса возврата при организации подпрограмм/функций определения размещаются расширяемом словаре;
– неявные параметры функций заранее размещаются в стеке, их число известно;
– результаты вычислений сконцентрированы в стеке.
Таким образом, обеспечены базовые функциональные возможности, характерные для систем программирования на языках высокого уровня.
Фрагмент программыПримечание(x y z → x y*z)
OVER (x y*z → x y*z x)
-
(x y*z x → x y*z - x)
SWAP (x y*z - x → y*z – x x)
DUP (y*z
– x x → y*z – x x x)
* (y*z
– x x x → y*z – x x*x)
+ (y*z
– x x*x → y*z – x + x*x)
Перемножение двух верхних элементов стека
Копирование второго элемента на верх стека
Разность двух верхних элементов
Перестановка двух верхних элементов
Дубль верхнего элемента
Перемножение двух верхних элементов
Сумма
Пример 2. Программа на языке Forth для подсчета по формуле
(x y z → x**2 + y*z – x)
Фрагмент программыПримечание: SQ
(вводится слово SQ в словарь)
DUP (A B
→ A B B)
* SWAP (A B B
→ A B**2 → B**2 A)
DUP * (B**2 A
→ B**2 A A → B**2 A**2)
+ (B**2 A
**2 → B**2 + A**2)
; (конец определения нового слова)
Объявление имени укрупнѐнного действия
Дубль верхнего элемента
Перемножение и перестановка
= Дубль и квадрат
Сумма – результат в стеке
Пример 3. Введение нового словаSQ для подсчета суммы квадратов
(A B → A**2 + B**2)
70
Для удобства программирования определений функций привлекается методика моделирования переменных и констант, а также средств управления процессами с помощью ветвления: условное выражение и переключатель, моделирование циклов.
Язык Forth – пример организации вычислений над стеком. Его можно рассматривать как язык-ядро с возможностью практически неограниченного проблемно-ориентированного расширения машинно- независимых эффективных средств программирования. Язык допускает порождение эффективного кода «хорошо» написанных программ.
Программирование на Forth-е требует вдумчивости и аккуратности.
Достижимость лаконичных форм дается
ценой нестандартных индивидуальных решений, мало приспособленных к передаче программ в чужие руки. Лозунги «Программируйте все сами!» и «Не бойтесь все переписывать заново!» правильно отражают подход к программированию на Forth-е. Успех достигается максимализмом в тщательной отладке и способностью видеть задачу программирования в развитии.
Автор языка Forth Чарльз Маури в 1968 году отметил: «Forth не уравнитель, а усилитель!».
К середине 70-х Forth стал третьим по популярности после Бейсика и
Паскаля, завоевав свои позиции при освоении микропроцессорных средств.
По технике программирования Forth похож на макроассемблер, только вместо системы команд над машинными словами в нем используется система операций на стеком.
Т аблица 18
Парадигматическая характеристика языка Forth Параметр Конкретика Эксплуатационная прагматика ЯП
Язык Forth – пример организации вычислений над стеком, применяемый как язык-ядро с возможностью практически неограниченного проблемно-ориентированного расширения машинно-независимых эффективных средств программирования. Допускает порождение эффективного кода «хорошо» написанных программ. Средство разработки специализированных систем, создаваемых по методике раскрутки, начиная с тщательно минимизированного ядра с рядом
71
последовательных шагов расширения в рамках единой оболочки. Мало приспособлен к передаче программ в чужие руки. Компактный язык-ядро для пошагового решения задач с расширяемой постановкой.
Регистры абстрактной машины
S E C
S – стек операндов и результатов.
E – словарь определений.
C – программа – поток операций и значений
Категории команд абстрактной машины
Преобразование содержимого стека.
Вычисление над стеком.
Применение программируемых определений
Реализационная прагматика
Стек – вектор заданного системой размера.
Элементы стека – слова фиксированной разрядности.
Система программирования использует пару интерпретатор-компилятор.
Парадигматическая специфика
Механизм реализации выражений в большинстве
ЯВУ.
Forth обладает концептуальным родством с языком
Lisp.
3.3. Продукционная макротехникаМакротехника дает весьма мощные, но не вполне безопасные средства повышения выразительности ЯП. Для макропроцессоров семантика ЯНУ обычно сопровождает средства работы со строками в стиле открытых процедур. Программа представляет собой поток макроопределений и макровызовов. Имена макросов могут рассматриваться равноправно с базовыми средствами. При определении и реализации макросов используется понятие позиции и шаблона для подстановки параметров.
Встречается стиль нумерации позиций, который позволяет обойтись без их именования в виде переменных. В результате подстановки макросов формируется текст,
равноправный с исходным, возможно, содержащий вторичные макросы. Макропроцессор часто используется в паре с ассемблером (макроассемблер) и другими ЯП. В качестве опорных рассмотрены макропроцессоры GPM, TRAC, а также два макропроцессора из системы подготовки программ на языке SETL.
Для автономных макропроцессоров характерны специальные механизмы регулярного конструирования различимых текстов:
– управляющие символы;
72
– счетчики;
– генераторы уникальных значений;
– блоки активности (разметка);
– встроенные функции;
– управление вводом-выводом.
Большинство макропроцессоров допускают переменные макропериода – глобальные и локальные макропеременные.
Для макропроцессора программа – это содержащий макровызовы текст, при обработке которого программа преобразуется в новый текст программы, полученный в результате макропреобразований:
Макро = (Прог = Текст): Прог → Прог'
Интерпретатор макропроцессора при последовательном сканировании текста выделяет в нем следующие категории строк:
– макроопределение, которое следует поместить в таблицу макросов
(c → e);
– макровызов без параметров, определение которого следует скопировать из таблицы в результат (e → c);
– макровызов с параметрами, значения которых следует установить, а затем подставить в буферную копию определения, и преобразованное определение разместить в результат (e → p → c);
– простая строка, сохраняемая в результате без преобразований;
– конец текста.
Абстрактный синтаксис макротекстов показывает появление функций с произвольным числом параметров, открыто подставляемых в шаблон определения.
(DEF Name Arg1 Arg2 … ArgN Patern) – разделители и ограничители сняты при переходе к АС.
(Name Txt1 Txt2 … TxtN) – однократная открытая подстановка текстов в место соответствующих аргументов.
Спецификация команд абстрактной машины макропроцессора может быть задана парой , в которой C – строка, а E – вектор определений.
73
Т аблица 19
Пример системы команд макропроцессора SCM
Описание команды Примечание LDF
Ввод шаблона макроса в таблицу под заданным именем.
Укрупнение действия.
LDN
Размещение параметра макроса в таблице под заданным номером.
Локальные параметры.
SP
Сцепление строки с текстом = обход строки.
Константа.
ARG
Копирование параметра в текст
Подстановка параметра.
AP
Применение макроса.
Применение макроса.
Т аблица 20
Спецификация макрокоманд RM
RM’
Примечаниеe (LDF Mac Ptn . c)
→ (e|e[Mac]:=Ptn) c
Размещение макроса в таблица определений. e (LDN Num Arg . c)
→ (e|e[Num]:=Arg) c
Размещение параметров в таблице определений. e (SP X . c)
→ e c
Пропуск константы. e (ARG Num . c)
→ e (e[Num] | c)
Подстановка параметра. e (AP Mac . c)
→ e (e[Mac] | c)
Подстановка макроса.
Макропреобразования могут использовать локальные или глобальные переменные, вложенность областей действия определений, рекурсию.
Макропроцессор
может быть встроен в компилятор, может быть автономным инструментом системы программирования, таким как текстовый редактор, оптимизатор или отладчик, или может существовать самостоятельно как универсальный инструмент общего назначения.
Макровызовы могут выполняться за одни просмотр или до исчерпания при итеративном анализе текста. Встречаются средства управления глубиной макроподстановки. Популярно синтаксическое подобие макросов выражениям базового языка, хотя это может вызывать путаницу в понимании реальных механизмов при порождении кода программы.
74
Техника строковой обработки обычно поддерживается операциями вычисления длины строки, выделения подстроки и конкатенации строк.
В системах программирования макротехника применяется на двух уровнях: препроцессоры обычно формируют входной текст для компилятора, а макроассемблеры выполняют сборку кода на уровне генерации ассемблерной программы или еѐ объектного кода.
Макропроцессор получает логическое завершение, поддерживая динамически формируемые макроопределения, возможно используя макровызовы в аргументах.
Встречается интересное применение вложенности макровызовов и макроопределений, включая рекурсию вида ФАКТ (сч) = если <сч = 0> то
[ 1 ] иначе [ ( | сч | +] | ФАКТ [ сч - 1 ] | [ ) ] .
Макроопределение
Примечание
ФАКТ (сч) = | <сч = 0> → [ 0 ]
| |
| [ ( | сч | * ]
| |
| ФАКТ [ сч - 1 ]
| |
| [ ) ]
ФАКТ (6) = (6 * (5 * (4 * (3 * (2 * (1 * 1))))))
Строка для значения 0
Строка из «(», значения «сч» и «*»
Строка из макроса от «сч», уменьшенного на 1
Строка из «)»
Результат макроса на значении 6
Пример 4. Рекурсивное макроопределение факториала
Макроопределение
Примечание
§A, §Def, A , ; §Def, B, ;;
Вызов «А», где «А» указывает на «D», а «В» на «С»
Пример 5. Пример макропрограммы на GPM.Моделирование « if A=B then C else
D
» обеспечено побочным эффектом на глобальной таблице имен
Техника выполнения макропреобразований достаточно разнообразна.
Так, например, язык GPM всю работу с макросами сводит к макровызову вида:
§ mak, a1, a2, ... aN; – вызов макроса.
Позиции макровызова занумерованы по числу предшествующих запятых, что делает ненужным описание переменных и дает возможность самоприменения определений:
75
0 1 2 ... N – описание не нужно.
Кроме того используются скобки, блокирующие подстановки при необходимости:
< S > – блокировка подстановок в S.
Достаточно всего одной встроенной функции DEF, выполняющей введение макроопределений.
Макроопределение
Примечание
§
Def, mak, опр;
Команда создания нового макроса
Пример 6. Введение новых макроопределений GPM
Макроопределение
Примечание
§Def, size, 6;
§size; => 6 x (§size, §size) => x(6,6) size§size => size6
Определение макроса
Варианты вызовов макроса
Пример 7. Использование макроопределений GPM
Макроопределение
Примечание
§Def, opp, UN1;
§opp, R;
§Def, opp, 1>;
§opp, R; => UNR
Параметр «1» вне подстановки
=> ОШ – нет определения
Параметр может быть подставлен
=> UNR
Пример 8. Использование блокировок в макроопределениях GPM
Совершенно иначе выглядит макротехника в не менее лаконичном языке макропроцессора TRAC. Все сводится к макровызовам функций, встроенных и определяемых:
# (F, s1,s2,...,sN)
Встроенные функции: ds – определение строки,
76
cl – вызов определение, ss – выделить сегменты, rs – чтение строки.
Макроопределение
Примечание
#(ds,ПРИМЕР, собака сидит на ковре)
#(ss,ПРИМЕР, собака, ковре)
#(cl,ПРИМЕР, кошка, кресле)
= кошка сидит на кресле
Исходная строка.
Выделены замещаемые сегменты.
Задана подстановка
= результат.
Пример 9. Работа с шаблонами на языке Trac
Два интересных механизма макротехники были реализованы в проекте языка Setl при попытке его эффективной реализации посредством языка
Little.
Для поддержки переноса программы на разные архитектуры предлагалась специальная разметка текста с помощью флагов, в зависимости от значения которых блоки строк включались во входной текст для компилятора. Значения флагов можно было инициировать, наращивать или редуцировать и обнулять.
+ flag – включить строку;
.flag – завершение блока, сопровождается увеличением или уменьшением счетчика, одноименного с флагом;
- flag – пропустить строку.
Для автоматизации формирования фрагментов текста, обладающих зависимостью от численных характеристик или кратности вхождения в программу, использовался специальный механизм специальных макропеременных.
77
Макроопределение ПримечаниеzxN => N + I zyN = N' => N' (zyN := N') zaN => A(N+i)
В строке размещается значение счетчика.
Задание значения спецпеременной.
В строке размещается имя ―A‖, сцепленное со значением счетчика.
Пример 10. Представление зависимости от процесса формирования текста
Общеизвестно, что макрос легче применять, чем определять. Внешняя простота введения макросов сопряжена с вероятностью порождения трудно обнаруживаемых ошибок периода исполнения программы, индуцированных случайным сходством с подпрограммами на основном языке программирования при существенном различии:
– макрос меняет текст программы,
– подпрограмма меняет данные программы и логику процесса исполнения программы.
Макротехника приносит результаты не только на текстах, но и на геометрических фигурах, графах и кодах. Например,
макросами можно описать пентамино, оптимизацию и кодогенерацию программ.
Иногда встречаются более специализированные средства, использующие счѐтчиковые переменные, конструкторы уникальных имен, моделирующие иерархию модулей или параметризирующие зависимость вариантов программы от целевых архитектур.
Определения Примечание#DEFINE THEN
#DEFINE BEGIN {
#DEFINE END ;}