Аннотация: Описание архитектуры вычислительной системы, как тогда представлялось - пятого поколения (условное название "А5"), ориентированной на объектные языки высокого уровня; предполагающей включать до 10^2 - 10^3 процессоров; обладающей свойствами расширяемости и живучести. Написано в 1988-90 г.г.
Весна не наступит, если дети
не будут рисовать солнце...
Настоящим описывается архитектура вычислительной системы, претендующая на
звание "архитектуры четвертого поколения". Из известных архитектур к этой
категории можно отнести только "Эльбрус", но в отличии от него, эта
предназначена для построения не супер, а мини и микро ЭВМ.
Настоящая работа является первым (даже предварительным) описанием данной
архитектуры. Она не претендует на полноту, ее цель - сформулировать основные
концепции. Сначала приводится довольно краткий обзор элементов архитектуры,
потом некоторые (наиболее интересные) вопросы рассматриваются более
подробно, далее описывается (в первом приближении) "базовая" модель процес-
сора и в заключении приводятся некоторые соображения относительно устройства
системного програмного обеспечения и базового алгоритмичесского языка.
1) Обзор архитектуры.
1.1 Общее описание.
Процессор представляет из себя двухстэковую теговую машину. Оперативная
память сегментированная. Типы и форматы данных распознаются аппаратурой.
Центральным элементом процессора является стэковый механизм. Он хранит про-
межуточные результаты вычислений и служебную информацию, используется при
выполнении всех действий процессора. (То есть выполняет ту-же роль, что и
"регистровый" механизм в других архитектурах.) Система команд безадресная,
организована по аналогии с "шитым кодом" фортоподобных языков. Обращение к
внешним устройствам - как к памяти. Система прерываний векторная. Имеется
аппаратная поддержка операционной системы и алгоритмичесских языков. Роль
ассемблера играет "базовый" язык, являющийся языком программирования высоко-
го уровня. Архитектура позволяет создать ряд моделей процессоров разного
назначения, разной производительности, разной разрядности и даже снабженных
отличающимися системами команд, но полностью програмно совместимых между со-
бой.
1.2 Память
Оперативная память представляется процессору в виде набора сегментов.
Каждый сегмент это массив (виртуальных) слов, содержащих значения одинаково-
го типа и формата. (В другом сегменте они могут быть другие.) Адресуется
каждое виртуальное слово; для обращения к нему требуется его смещение в
сегменте и указатель на сегмент ("селектор"). Смещение это обычное целое
число, а селектор сегмента - значение специального аппаратно распознаваемого
типа.
Виртуальная память некоторым образом отображается на физичесскую, реально
существующую "запоминающую среду". Как именно - зависит от режима адресации.
Режимов два - "начальный" и "основной". (Возможен третий режим - "расширен-
ный", его предполагается использовать в "старших" моделях.) В обоих режимах
сегмент целиком размещается в оперативной памяти и состоит из заголовка и
тела. Тело содержит последовательность виртуальных слов, а заголовок - неко-
торые аттрибуты сегмента. Он програмно недоступен. Режимы отличаются тем,
что в начальном - адрес начала сегмента содержится в его селекторе, а в
осносном - в "дескрипторе" сегмента, а селектор содержит номер дескриптора в
таблице сегментов. (Можно сказать, что в начальном режиме используется пря-
мая адресация, а в основном - косвенная.) Начальный режим позволяет исполь-
зовать единственную запоминающую среду весьма ограниченного объема и исполь-
зуется при начальном пуске процессора для формирования различных таблиц (в
частности таблицы сегментов).
Различные аттрибуты сегмента (его текущая длинна, тип и формат содержа-
щихся в нем данных, принадлежность процессу, и т.д.) помещаются в дескрипто-
ре сегмента, а некоторые из них (те, которые необходимы в начальном режиме)
- в его заголовке.
1.3 Стэковый механизм.
В процессоре имеется два стэка - управляющий и операционный. Операционный
стэк используется для работы с данными. В нем хранятся промежуточные резуль-
таты вычислений, локальные переменные. Все операции выполняются над данными,
находящимися на вершине операционного стэка. В управляющем стэке сохраняется
информация, используемая для управления работой программы. Каждый стэк
размещен в собственном сегменте. Оба растут в направлении старших адресов.
Операционный стэк состоит из самоопределяемых данных - теговых слов. С
ним связано три внутренних регистра: указатель вершины, указатель локального
дна, и указатель базы. Первые два указывают текущие границы активной части
стэка. Последний содержит базу "записи активации" - набора локальных пере-
менных, и используется для обращения к ним. (Возможно он дополнен регистром
длинны записи активации.)
Управляющий стэк содержит последовательность самоопределяемых записей,
хранящих служебную информацию. За одно обращение в него помещается или
извлекается целиком одна такая запись. На дне управляющего стэка (в начале
его сегмента) содержится запись, называемая "заголовком процесса". Она опи-
сывает один из процессов. (Собственно не заголовок процесса находится в
сегменте управляющего стэка, а наоборот - управляющий стэк находится в
сегменте заголовка процесса.)
1.4 Организация программы.
Программа размещается в сегментах типа "сегмент команд", каждая подпрогра-
мма в собственном. Точка входа в подпрограмму единственная - начало
сегмента. (Поэтому для обращения к ней нужен только селектор.) При активиза-
ции подпрограммы одно слово из служебной части ее сегмента загружается не-
посредственно в регистр состояния процессора и задает режим выполнения этой
подпрограммы. (Регистр состояния процессора сохраняется в управляющем стэке
вместе с адресом возврата.)
Система команд - безадресная. Большинство команд состоит только из кода
операции, но есть - с непосредственным операндом, размещаемым вслед за ко-
мандой. Система команд включает в себя: а) Команды преобразования информации
(арифметичесские, логичесские, побитовые, сравнения, и т.п.). б) Команды ре-
организации вершины стэка. в) Команды преобразования типов. г) Команды пере-
сылки информации с/на стэк. д) Команды засылки на стэк констант. е) Команды
управления выполнением программы. ж) Специальные команды.
Сегмент команд это последовательность слов, каждое из которых - код
"встроенной" команды (непосредственно выполняемой процессором), или селектор
сегмента подпрограммы (что эквивалентно обращению к ней и можно считать
"определяемой" командой). Если содержимое слова меньше 256, то это встроен-
ная команда, иначе "определяемая". Подпрограмма, так же как и встроенная ко-
манда, может использовать непосредственный операнд. Его наличие и размер
указывается одним из признаков, загружаемых в регистр состояния процессора
при активизации подпрограммы.
1.5 Процессы.
Единицей работы является "процесс". Процесс отождествляется с "заголовком
процесса" и интендифицируется уникальным номером. Каждый процесс имеет
собственные операционный и управляющий стэки. (Последний размещается в одном
сегменте с заголовком процесса.)
Переключение процессов производится аппаратно. Процесс активизируется (по-
лучает процессор) в результате передачи управления на его сегмент заголовка.
Это может произойти как по инициативе активного в настоящий момент процесса,
так и в результате прерывания.
Для синхронизации параллельных процессов используется семафорный механизм.
Семафором может служить любой сегмент: каждый сегмент принадлежит одному из
процессов, или является общедоступным (принадлежит процессу номер ноль).
Процесс не может использовать чужой сегмент (возникнет ситуация), но может
попытаться присвоить его (или сделать общедоступным). Это разрешается (или
запрещается) одним из аттрибутов сегмента (изменить который может только
процесс-хозяин). Имеется неделимая операция, присваивающая сегмент процессу
и одновременно сбрасывающая признак разрешения присвоения. Она эквивалентна
закрытию семафора. Если семафор уже закрыт, то процесс приостанавливается.
Управление передается другому процессу, а именно тому, которому принадлежит
сегмент-семафор. (Чтобы он быстрее прошел "критический" участок и открыл
его.) При повторной активации приостановленного процесса, делается попытка
снова выполнить эту операцию.
Тупики (взаимная блокировка процессов) обраруживаются следующим образом:
попытка закрыть семафор, следующая за ним приостановка процесса и активация
другого происходят как одна неделимая операция; если этот, другой процесс
тоже неудачно пытается закрыть семафор, активируется следующий процесс - хо-
зяин этого другого семафора. И так далее. Если очередным процессом в этой
цепочке окажется первый - имеет место тупик. Для его преодоления во всех
блокирующих друг друга процессах порождается соответствующая ситуация. Если
очередной процесс не существует - необходимо вмешательство операционой
системы (происходит прерывание).
Порождение, диспетчеризация и уничтожение процессов производит системное
програмное обеспечение. "Естественный" конец процесса наступает когда про-
исходит возврат из его "головной" подпрограммы. В этом случае происходит
прерывание, дабы операционная система произвела утилизацию принадлежавших
ему ресурсов.
1.6 Система прерываний.
Прерывания предназначены для организации реакции программы на внешние по
отношению к ней события. В начальной области памяти содержатся "вектора пре-
рываний", каждый из которых включает селектор сегмента и дополнительную
информацию. Каждый вектор соответствует некоторому внешнему событию, со-
держащийся в нем селектор указывает на процесс или подпрограмму, которая
должна среагировать на это событие. Если это процесс, то он активируется (но
в отличии от случая передачи ему управления другим процессом, порождается
ситуация (на момент прерывания процесс мог быть уже активным)), если это
подпрограмма, то порождается временный процесс. Он не имеет собственных стэ-
ковых сегментов, а использует принадлежащие текущему. (В управляющий стэк
помещается "временный заголовок процесса" а в основном заголовке об этом де-
лается специальная отметка.) Временный процесс рассчитан на то, чтобы
быстренько сделать некоторое действие и закончиться, вернув управление
постоянному. Если делается попытка активировать постоянный процесс, "на шее"
у которого сидит временный - требуется вмешательство операционной системы.
Ожидание прерывания производится с помощью команды, аналогичной команде
"wait" в PDP-11. Она передает управление другому процессу, а при возобновле-
нии данного повторно выполняется (как и команда закрытия семафора). Тоесть
вводит процесс в такое состояние, из которого он может выйти только в ре-
зультате возникновения в нем ситуации.
Управление прерываниями производится с помощью двух разных признаков в ре-
гистре состояния процессора. Один из них запрещает обработку внешних преры-
ваний (вообще, или с приоритетом ниже указанного им). Второй запрещает
использовать при прерывании ресурсы текущего процесса - не может быть по-
рожден временный процесс, только активирован ранее существующий. Кроме того
он запрещает порождение ситуации в текущем процессе в результате внешнего
прерывания.
1.7 Модели.
На базе описываемой архитектуры можно построить много разных процессоров,
отличающихся разрядностью, объемом адресного пространства, производитель-
ностью и даже имеющих разные системы команд. Все эти модели можно разделить
на три группы: "младшие", "средние" и "старшие". Базовая модель процессра
относится к "средним".
Младшие модели сопоставимы с 8-и разрядными микропроцессорами и предназна-
чены для изготовления микроконтроллеров. Они имеют минимальный объем аппара-
туры, работают под управлением программы, зашиваемой в ПЗУ, используют толь-
ко начальный режим адресации и их совместимость с остальными моделями огра-
ничена. Средние модели аналогичны 16-и разрядным, а старшие - 32-х разрядным
машинам. Они (в отличии от младших) снабжаются внешними запоминающими
устройствами прямого доступа, работают под управлением операционной системы,
могут образовывать многопроцессорные конфигурации.
Размер селектора сегмента базовой модели - всего 12 разрядов. Именно это
обстоятельство позволяет с одной стороны разместить таблицу сегментов цели-
ком в оперативной памяти, и организовать систему команд по аналогии с шитым
кодом. Но с другой стороны, пространство сегментов оказывается всего около
4000, что совсем не много. Oсобенно если учесть, что в данной архитектуре
каждый элемент данных и каждая подпрограмма размещаются в собственном
сегменте. Это накладывает ограничения на максимальный размер задачи, которую
способна решить подобная вычислительная система. (Поэтому для базовой модели
нет смысла стремиться к большой разрядности, сверхвысокому быстродействию
или строить многопроцессорные комплексы, содержащие более трех - четырех
процессоров.)
Размер селектора "старших" моделей достаточно велик, чтобы избавиться от
вышеуказных ограничений. Следствиями этого является во-первых необходимость
пересмотра способа организации системы команд. (Либо она должна быть "более
традиционной", либо "настоящие" селекторы следует получать из 12и разрядных
с помощью "таблицы преобразования", своей собственной для каждой задачи.) А
во вторых нужен новый режим адресации - "расширенная", позволяющий размещать
слишком длинные сегменты (и в том числе таблицу сегментов) в основном во
внешней памяти, а в оперативной только частично. Для этого их видимо при-
дется разбивать на страницы. На настоящем этапе старшие модели рассматри-
ваться не будут.
Архитектура младших моделей - сильно сокращенный вариант базовой. Защита
памяти и средства поддержки операционной системы контроллерам совершенно не
нужны. Размер физичесского и виртуального слова совпадают (12 разрядов), са-
моопределяемые данные не используются (кроме записей в управляющем стэке).
Режим адресации - только начальный. Типы данных - только битовый набор длин-
ной в одно слово. Програмная совместимость с другими моделями частичная.
Используется тот-же самый базовый язык, но с существенными ограничениями ти-
пов и форматов данных. Система команд организована так-же, как в средних мо-
делях, но набор команд должен иметь достаточно существенные отличия в
следствии невозможности работать с разныными форматами и аппаратно распозна-
вать типы.
2) Стэковый механизм процессора.
Стэковый маханизм это центральный элемент архитектуры процессора. Вся дея-
тельность процессора происходит при его участии. В этом разделе мы более
подробно рассмотрим его работу. Общие сведения о его устройстве см. в п.1.3.
2.1 Представление данных в стэках.
Данные в обоих стэках самоопределяемые - кроме "полезной" информации
каждый элемент данных содержит сведения о том, что он обозначает.
В операционном стэке самоопределяющийся элемент - "теговое слово", а сам
стэк размещается в сегменте теговых слов. Каждое из них имеет аппаратно
распознаваемое поле - тег. Короткие значения (например короткое целое, се-
лектор сегмента) занимают одно теговое слово, тег указывает их тип. Длинные
значения (например плавающее число) занимают последовательность из несколь-
ких смежных теговых слов. Первое из них содержит тег, обозначающий начало
такой последовательности, остальные, кроме последнего - тег "продолжение", а
последнее - тег указывающий тип значения. Такая последовательность участвует
во всех операциях как единое целое. Длинными могут быть значения информаци-
онных типов (их всего три - целое, вещественное и битовый набор) и "пустое"
значение. Данные служебных типов как правило короткие. Данные, пересылаемые
на стэк, преобразуются в одно или несколько теговых слов, в таком виде над
ними производятся все действия. При обратной пересылке производится преобра-
зование к типу и формату сегмента, если оно вообще возможно. (Иначе возни-
кает соответсвующая ситуация.) При записи в сегмент теговых слов контроль
форматов должна производить сама программа. (Иначе конец слишком длинного
значения может наложиться на начало следующего.)
В управляющем стэке самоопределяющейся является запись. Записи могут быть
разной длинны, их конкретное устройство определяется реализацией. Помещение
и извлечение записей из управляющего стэка производится только с вершины.
"Выдернуть" запись из середины невозможно. Независимое обращение возможно
только к самой первой записи - заголовку процесса, находящемуся на дне
управляющего стэка (тоесть в начале его сегмента) и имеющему фиксированый
формат. При необходимости получить запись некоторого определенного типа
(например адрес возврата из подпрограммы при выполнении операции возврата)
из стэка извлекаются все записи подряд, пока не будет найдена подходящая.
Каждая извлеченная запись сразу используется "по прямому назначению".
(Например, если это сохраненное содержимое некоторого внутреннего регистра
процессора - оно восстанавливается.) При попытке извлечь последнюю запись
(заголовок процесса) происходит прерывание, в результате которого должна
активизироваться операционная система и ликвидировать этот процесс.
2.2 Использование стэков.
Управляющий стэк используется некоторыми командами для храниния служебной
информации. Поместить туда что либо "по желанию" программы невозможно.
Данные, с которыми работает процессор, помещаются на вершину операционного
стэка, пополняя его активную часть. Все операции берут оттуда свои операнды
и помещают на их место результат. Для выполнения вычислений с помощью стэка,
выражения преобразуются в обратную польскую безскобочную запись. Результат
вычисления выражения тоже остается на вершине стэка.
Активной является часть стэка между вершиной и локальным дном. Если верши-
на и локальное дно совпадают, стэк считается пустым. Снять значение с пусто-
го стэка нельзя (возникает ситуация). Блок, ограниченный операторными
скобками (типа "begin" и "end") начинается с команды, устанавливающей ло-
кальное дно на вершину и сохраняющей его значение в управляющем стэке, и за-
канчивается командой, производящей обратные действия. В результате данные в
стэке оказываются защищенными от изменения командами блока, а сам блок вы-
полняется с пустого стэка. Блок (предположительно) содержит последователь-
ность операторов. Каждый из них выполняется с пустого стэка, и в конце очи-
щает стэк от результатов своей работы с помощью команды, соответствующей за-
вершающей его точке с запятой и уничтожающей все содержимое стэка до локаль-
ного дна. (Обычно она называется "опустошение".) Если выражения в скобках
разделяются запятыми, то их значения накапливаются на стеке (образуя, напри-
мер, список параметров подпрограммы).
2.3 Передача параметров.
Обращение к подпрограмме происходит самым обычным образом - ей передается
управление, а адрес возврата сохраняется в управляющем стэке. Он, кстати,
включает в себя селектор сегмента команд, смещение и слово состояния процес-
сора. Возврат происходит по достижении конца сегмента команд или по команде
возврата из подпрограммы. Адрес возврата извлекается из управляющего стэка,
и, как указано в п.2.1, все записи, помещенные после него - тоже. Так что
если в подпрограмме и было изменено положение локального дна, после возврата
оно будет восстановлено таким, каким было в момент обращения.
Передача параметров подпрограмме тоже производится через стэк. Подпрограм-
ма должна сама позаботиться о том, чтобы убрать их оттуда и оставить резуль-
тат. (Машинные команды делают в точности то-же самое.) Если количество пара-
метров фиксировано и подпрограмма сделает, что от нее требуется, никаких до-
полнительных мер предпринимать не надо. Однако желательно накапливать список
параметров с пустого стэка. (В дальнейшем будет считать, что так оно и
есть.)
Как правило, переданные (фактичесские) параметры становятся в подпрограмме
начальными значениями локальных переменных, объявленных в ее заголовке (и
называемых формальными параметрами). Для этого используется специальная ко-
манда. Она превращает активную часть стэка в новую запись активации (набор
локальных переменных). Указатель базы записи активации устанавливается на
место локального дна, старое его значение сохраняется в управляющем стэке.
Локальное дно при этом устанавливается на вершину (тоесть стэк становится
пустым). Перед этой операцией, возможно, вершина стэка должна быть реоргани-
зована: проверены (и скорректированы) форматы переданных параметров, до-
бавлены начальные (пустые) значения для прочих локальных переменных. Это
можно сделать одной специальной командой. После этого предыдущий список ло-
кальных переменных становится недоступным.
При извлечении из управляющего стэка сохраненного значения регистра базы
(например в процессе возврата из подпрограммы) последняя запись активации
ликвидируется, активная часть стэка переносится на то место, где было ло-
кальное дно в момент ее создания. (Активная часть стэка предположительно со-
держит возвращаемые подпрограммой значения.) Положение локального дна и ука-
зателя базы восстанавливается. Таким образом использованный список пара-
метров удаляется автоматичесски, без усилий со стороны программы.
Описаный механизм позволяет передавать любой подпрограмме без катастрофи-
чесских последствий большее или меньшее число параметорв, чем она ожидает
(недостающие формальные параметры получат пустое значение, лишние фактичес-
ские параметры станут начальными значениями "прочих" переменных). А также
возможна обработка массива параметров неопределенной длины.
2.4 Механизм ситуаций.
"Структурный переход" это структурное средство передачи управления,
предназначенное для описания поведения алгоритма в "аномальных" случаях.
Аномальное состояние называется "ситуацией", оно возникает по инициативе
программы или вследствии различных ошибок. Если возникновение ситуации ожи-
дается, т.е. на нее была установлена хотя бы одна "ловушка", происходит
структурный переход к месту установки ловушки, выполняется указанная в ло-
вушке реакциия и программа нормально продолжается. Если возникновение ситуа-
ции не ожидалось - процесс аварийно заканчивается.
С помощью структурного перехода можно просто выйти из цикла, когда сложи-
лись условия его окончания (аналогично оператору "break" языка Си), можно
организовать рекурсивный выход из подпрограмм (например возврат в алгоритме
"перебор с возвратами"), а можно использовать его в случае когда функция не
может выполнить некоторые действия (вмето того, чтобы устанавливать перемен-
ную "errno" и возвращать "специальное" значение). Аналогами структурного пе-
рехода являются "прерывания" в ПЛ-1, "исключения" в Аде, а так-же механизм
"setjmp/longjmp" в Си. Однако в полном объеме он реализован только в Эль-76
(автокоде Эльбруса), так как для эффективной реализации нуждается в аппа-
ратной поддержке.
Ситуация возникает при различных ошибках (исчерпании стэка, обращении за
пределы сегмента, делении на ноль, использовании операнда недопустимого ти-
па), при переполнении, обнулении результата операции, переносе, что управля-
ется признаками в слове состояния процессора, при передаче управления про-
цессу по прерыванию, а так-же по инициативе программы (специальной ко-
мандой). Ловушка на ситуацию устанавливается соответствующей командой - в
управляющий стэк помещается запись типа "ловушка". Она содержит номер ситуа-
ции и ссылку на подпрограмму реакции. (Последняя может отсутствовать.) Ло-
вушка локальна внутри фразы, где она установлена. При извлечении ее из стэка
в процессе поиска записей других типов никаких действий не предпринимается.
Подпрограмма реакции - самая обычная. Ей, как и другим подпрограммам, могут
быть переданы параметры и она может возвратить результат. ("Искуственная"
организация ситуации очень похожа на обращение к подпрограмме, а при ее
"естественном" возникновении передаются стандартные параметры).
При возникновении ситуации выполнение программы прерывается и начинается
поиск ловушки нужного типа в управляющем стэке. При этом (как описано в
п.2.1) извлекаются все записи подряд и к моменту нахождения ловушки положе-
ние локального дна, базы записи активации и регистра указывающего активный
сегмент команд будут такими-же, как и в момент ее установки. После этого
ликвидируется все содержимое стэка, находящееся между положениями локального
дна на момент возникновения ситуации и текущим. Активная часть стэка
(предположительно содержащая аргументы для подпрограммы реакции) переносится
на его место. После этого в управляющем стэке сохраняется фиктивный адрес
возврата и управление передается подпрограмме реакции (если она есть). После
ее окончания, как обычно, ищется адрес возврата. Нахождение фиктивного адре-
са возврата приводит к тому, что поиск продолжается, но теперь ищется не
только "настоящий" адрес возврата, но и "границы блока". В результате про-
исходит выход из подпрограммы или блока, внутри которых была установлена ло-
вушка, при этом возвращается то значение, которое оставлено на стэке
подпрограммой реакции.
2.5 Возможная реализация.
Оба стэка размещаются в отдельных сегментах и растут от младших адресов к
старшим. Часть операционного стэка между вершиной и дном активно использу-
ется при выполнении большинства операций процессора, размещение ее в опера-
тивной памяти не эффективно и допустимо только на самых младших моделях. В
остальных она должна быть организована на регистрах. Рассмотрим один из ва-
риантов ее организации.
Имеется регистровый пул, содержащий N регистров. N - степень двойки (16,
32, или даже 64). В этих регистрах хранится верхушка стэка. Имеется
M-разрядный реверсивный счетчик. M=log2(N). Он указывает регистр, в котором
хранится слово, находящееся на вершине стэка. Каждый регистр снабжен двумя
признаками, "есть" и "новый". Признак "есть" обозначает, что в регистре не-
кая полезная информация. Признак "новый" - что она еще не скопирована в па-
мять.
При помещении слова на стэк, содержимое счетчика увеличивается на единицу,
запись производится в указываемый им регистр, оба признака устанавливаются.
При снятии слова со стэка, оно берется из регистра, номер которого в счетчи-
ке, у этого регистра оба признака сбрасываются, содержимое счетчика уменьша-
ется. Переполнение и обнуление счетчика игноринруются, в результате ре-
гистровый пул как-бы замкнут в кольцо.
Имеются два независимых механизма, один из которых занимается подкачкой
данных в регистровый пул из памяти, а второй откачкой их в память. Каждый из
них выбирает регистр (с установленным признаком "новый" или сброшенным
"есть") и пытается запустить операцию чтения (или записи) слова, которому
этот регистр соответствует. Оба они обращаются к ОЗУ через общее для всего
процессора устройство связи с памятью. Причем их приоритет самый низкий во
всем процессоре, а относительный приоритет тем выше, чем дальше найденый
устройством регистр от текущей вершины стэка. (С внутренней или внешней сто-
роны соответственно.) Чтение из регистра имеет смысл только если признак
"есть" установлен, а запись в него (со сдвигом вершины стэка) разрешается
только если признак "новый" сброшен. Если регистр, к которому процессор хо-
чет обратится, имеет неверные признаки, процессор приостанавливается и ждет,
пока один из механизмов не подкачает (или не откачает) данные. Таким образом
один механизм следит, чтобы регистры была максимально заполнены полезной
информацей, а другой - чтобы было место для записи новой. В то-же время они
стараются не производить лишней работы.
При переключении процессов, и выполнении "неделимых" операций синхрониза-
ции необходимо принудительно сбрасывать в ОЗУ содержимое регистрового пула.
При передаче параметров, если список параметров не слишком велик и целиком
умещается в регистровом пуле, не требуются никакие реальные пересылки дан-
ных, достаточно установить значения указателей дна вершины и базы. При на-
чальном пуске процессора можно некоторое время вообще обходится без сегмента
операционного стэка и работать только с регистровым пулом процессора. (Но
при этом надо заблокировть откачку данных в память.)
3) Память.
С точки зрения программы, память представляет из себя набор сегментов.
Сегмент - это линейная последовательность слов, ограниченой длины. Для обра-
щения к некоторому слову используется селектор сегмента и смещение. Селектор
это значение специального типа. Программа получает его в готовом виде и не
может модифицировать. С ее точки зрения существуют только те сегменты, се-
лекторы которых имеются в ее распоряжении. Смещение же - это обычное положи-
тельное целое число. С ним можно производить любые манипуляции, но если оно
окажется больше текущего размера сегмента, то обращение не производится, а
возникает ситуация соответствующего типа. Виртуальные слова, из которых
состоит сегмент, в разных сегментах имеют различный размер и тип. (В одном
сегменте тип и размер слов как правило одинаковы. Иное не исключается, но
вряд-ли целесообразно.)
3.1 Режимы адресации.
Способ, с помощью которого память организуется такой, какой она видится
программе, называется режимом адресации. В одном процессоре может быть реа-
лизовано несколько таких режимов. Виртуальная память отображается на физи-
ческую. Тоесть по селектору и смещению, используемым для обращения к вирту-
альному слову, определяются физические слова, на которые оно отображается и
производится обращение к ним. Это может быть сделано самыми разнообразными
способами, зависящими как от режима адресации, так и от модели процессора.
Можно выделить "начальный", "основной" и "расширенный" режимы адресации.
"Основной" режим предполагает с одной стороны косвенное обращение к физи-
ческой памяти - с помощью таблиц, хранящихся в ОЗУ. (Например таблицы
сегментов - селектор указывает на элемент этой таблицы, а он содержит аттри-
буты сегмента, в том числе сведения о его размещении в памяти.) С другой
стороны и эти таблицы и сегменты целиком размещаются в оперативной памяти.
Т.е. максимальный размер сегмента и их количество не слишком велико.
"Начальный" режим, в отличии от основного, предполагает прямое обращение к
памяти (адрес начала сегмента содержится в селекторе), и предназначается в
основном для формирования различных таблиц при начальном пуске процессора.
Объем доступной в начальном режиме оперативной памяти очень ограничен. "На-
чальный" режим предполагается использовать в качестве единственного в
младших моделях, предназначенных в основном для построения простейших
контроллеров. (Из за его простоты, экономичности, отсутствия накладных
расходов, для минимизации объема аппаратуры.) Контроллер как правило не
нуждается в большом объеме памяти.
Расширенный режим допускает использование значительно более длинных
сегментов, чем основной. (И самих сегментов может быть гораздо больше.) Это
влечет за собой, с одной стороны необходимость разбиения сегмента на части
(страницы или субсегменты) и хранения его в основном во внешней памяти, а с
другой - требуется селектор сегмента большего размера. Это требует пе-
ресмотра других элементов архитектуры (см. п.1.7).
3.2 Физическая организация.
Физическая память состоит из одной или более запоминающих сред. Запоминаю-
щая среда это нечто вроде "физического сегмента" - конечная последователь-
ность физических слов. У разных запоминиющих сред размер слова в общем слу-
чае может быть различным. Отдельными запоминающими средами будут, например,
резидентная память каждого поцессора, пространство управляющих регистров
внешних устройств, экранная область, оформленная в виде отдельного устрой-
ства.
Все устройства подключаются к общей шине. Через нее они "общаются" между
собой. Устройства делятся на "активные" и "пассивные". Все операции на общей
шине происходят "по инициативе" активных устройств. В каждый момент времени
шина принадлежит одному из них. Каждое пассивное устройство - отдельная за-
поминающая среда (или ее часть).
При первоначальной реализации базовой модели предполагается использовать
общую шину микро-ЭВМ семейства Электроника-60 (или 60.1). Это позволит
использовать имеющийся у этого семейства богатый набор внешних устройств.
Запоминающих сред будет две: оперативная память и внешние устройства. Размер
физического слова - 16 разрядов. В однопроцессорном варианте шина (и ее про-
токол) подходят без всяких переделок; в многопроцессорном придется использо-
вать одну из резервных линий для сигнализации о факте выполнения неделимой
операции.
"Полная" реализация предполагает использование собственного канала,
предназначеного для пакетной передачи слов разной разрядности. Размер пере-
даваемого слова предполагается кратным четырем битам (тетраде).
В одной операции обмена участвуют два устройства - активное и пассивное.
Обмен происходит по инициативе активного устройства. Оно обращается к одному
из пассивных, указывая номер соответствующей ему запоминающей среды и адрес
слова в ней. Если пассивное устройство существует, оно должно откликнуться,
после чего активное указывает операцию и начинается передача данных.
Передача данных ведется "по слогам". Причем шириной слога - количеством
информации, передаваемой за раз - управляет пассивное устройство. Для этого
имеется специальная шина ширины слога. Кроме того оно указывает что данных
слог в слове последний. Передаваемое слово разбивается на части, не превыша-
ющие ширины шины данных и возможностей обоих участвующих в обмене усторйств.
Максимальную ширину слога устанавливает активное устройство (сообщает всем
пассивным при захвате канала), с учетом ширины канала, которая устанавлива-
ется на нем аппаратно (например перемычками). Например: шина данных 32
разряда, активное устройство 16 разрядов, пассивное 24 разряда, передается
36и разрядное слово. Оно будет разбито на три слога по 16, 16 и 4 бита.
Активное устройство управляет обменом устанавливая на шине команд код те-
кущей операции. Предполагается четыре операции: чтение очередного (следующе-
го) слова, запись очередного слова, запись того-же слова (чтение которого
производилось только-что), прекращение обмена. Активное устройство может
прервать текущую операцию на любой стадии и указать следующую.
Таким образом канал позволяет передавать по нему группы последовательно
расположенных слов. Как физических так и виртуальных. При передаче группы
физических слов, на которые отображается одно виртуальное, активное устрой-
ство отвечает за маскирование разрядов, не используемых в данном виртуальном
слове. Для этого и предназначена операция "запись того-же слова". Для обмена
виртуальными словами необходимо с одной стороны обеспечить передачу их
аттрибутов (типа и формата), а с другой - надо чтобы пассивное устройство
(запоминающая среда) было весьма самостоятельно. В частности содержало (и
поддерживало) нечто вроде таблицы сегментов.
3.3 Способы обращения к памяти.
Способов получения по виртуальному адресу виртуального слова гораздо боль-
ше чем режимов адресации. Поэтому в разных моделях один и тот-же режим адре-
сации может быть реализован различным образом.
Самый младший "начальный" режим предполагает что в селекторе содержится
физичесский адрес начала сегмента. Но это может быть только старшая часть
адреса, а два или четыре младших разряда - нулевые. В младших моделях к
адресу начала сегмента прибавляется смещение и получается физический адрес
нужного слова. В более старших моделях размер физического слова может не
совпадать с размером виртуального (параметры которого содержатся в заголовке
сегмента), так что еще придется пересчитать смещение и возможно считать (за-
писать) не одно, а группу слов. Обращение ведется к единственной запоминаю-
щей среде. Нулевой селектор используется для обращения ко всей оперативной
памяти, селектор с максимальным номером - к внешним устройствам. (Со-
ответствующий ему сегмент целиком находится за пределами ОЗУ.)
Простейший вариант основного режима - имеется единственная таблица
сегментов. Селектор содержит номер элемента этой таблицы. А он - разные
аттрибуты сегмента, в том числе номер запоминающей среды и физичесский адрес
его начала. Могут быть дополнительные данные, используемые при распределении
памяти, например количество места, занимаемого сегментом. (Расстояние до
следующего сегмента.)
Более сложный вариант - таблица сегментов разбивается на части, эти части
(например при переключении задач) заменяются. То есть имеется масса
подтаблиц, и использовать их для учета и распределения памяти затруднитель-
но. В этом случае целесообразно ввести общую (или свою собственную для
каждой среды) таблицу распределения памяти, пока только для нужд операцион-
ной системы.
Следующим логичесским шагом будет помещение в элемент таблицы сегментов не
физичесского адреса, а ссылки на элемент таблицы распределения памяти (если
сегмент находится в ОЗУ) или на некую другую таблицу (если в другом месте,
например на диске).
Следующим шагом является аппаратное обособление запоминающих сред, обмен с
ними не физичесскими, а виртуальными словами (для чего и придумана описанная
выше пакетная шина), усложнение структуры памяти. Например разбиение ее на
страницы. Это позволит увеличить максимальный размер сегментов, облегчить
изменение размеров сегмента. Но возможно потребует снабжение запоминающей
среды собственным специализированным процессором.
При увеличении размера селектора (в старших моделях) потребуется предпри-
нять меры для хранения очень большой (и возможно редкозаполненной) таблицы
сегментов. Однако от таблицы сегментов можно отказаться совсем, перенеся
аттрибуты сегмента в его заголовок или в элемент таблицы распределения памя-
ти. В селектор можно поместить номер элемента этой таблицы вместе с номером
запоминающей среды (предполагается, что у каждой запоминающей среды таблица
распределения памяти своя собственная). В этом случае, возможно, придется
отказаться от концепции принадлежности сегментов процессам и основанного на
этом механизма синхронизации процессов. (Впрочем не велика потеря -
пространство сегментов будет достаточно большим.) Номер запоминающей среды в
селекторе будет достаточно коротким 3-5 бит. Если он абсолютный, то это не
вносит ничего принципиально нового по сравнению с "основным" режимом. Но
если он относительный - вот тут начинается самое интересное. Получается
адресное пространство, ограниченное горизонтом. Оно позволяет построить ма-
шину, состоящую из неограниченного числа процессоров, но впрочем это уже
другая история...
3.4 Сегменты специального типа.
Они предназначены для хранения управляющей информации, не связанной с ка-
ким-то отдельным процессом. Они, как и сегменты данных, могут быть различных
подтипов. К данным, хранящимся в сегменте специального типа, разрешается
доступ только в случае, если в слове состояния процессора установлен специ-
альный признак. Иначе, в зависимости от подтипа сегмента либо возникает си-
туация "привилигированные действия", либо происходит прерывание, либо за-
пускается системная процедура, предназначенная для работы с данным
сегментом.
В сегментах специального типа размещаются различные таблицы операционной
системы (в частности таблица сегментов). Они используются для представления
"внешних" объектов, а так-же больших и многомерных массивов. В последнем
случае сегмент содержит количество измерений массива, его размеры по разным
координатам и список селекторов сегментов, в которых на самом деле размеща-
ются данные массива. При попытке обращения к такому массиву вызывается
системная процедура, которая берет со стэка индексы, вычисляет местоположе-
ние данных и производит чтение или запись.
В более старших моделях манипуляции с сегментами специального типа предпо-
лагается реализовать аппаратно. В общем-то сегменты этого типа сейчас
по-настоящему не используются. Они предназначены для дальнейшего развития
архитектуры.
3.5 О реализации.
Реализация описанной модели памяти представляет из себя достаточно сложную
проблему.
При каждом обращении в оперативную память приходится использовать информа-
цию из служебной части сегмента и его дескриптора. Чтобы предотвратить мно-
гократные обращения в таблицу сегментов, в процессоре необходимо иметь спе-
циализированную кэш-память, специально предназначенную для хранения этих
данных. Без такого устройства процессор будет работать крайне неэффективно.
Гораздо больше неприятностей доставляет несовпадение длин физического и
виртуальных слов. Чтобы получить адрес физического слова, соответствующего
виртуальному, смещение необходимо умножить на длину виртуального слова,
разделить на длину физического, и к полученному результату добавить адрес
начала сегмента. Остаток от деления - номер тетрады в физическом слове, с
которой начинается виртуальное. Умножение и деление операции "дорогие", но
если учесть, что длина физического слова - степень двойки, то деление сво-
дится просто к отделению двух младших разрядов произведения (которые
представляют собой остаток). А так как длина слова короткое целое число, то
умножение нетрудно выполнить при помощи многоразрядного "гиперсумматора".
(Это комбинационная схема, аналог полного сумматора. Имеет 7 входов и
трехразрядный выход, куда выдается двоичное число, указывающее количество
единиц на входах (0 - 7). В многоразрядной схеме младший выход - очередной
разряд результата, а два других используются для переноса в следующий и
постследующий разряды. Реализация гиперсумматора на обычной логике доста-
точно сложна, поэтому стоит рассмотреть возможность его реализации с исполь-
зованием принципов нечеткой логики (например на ЭСЛ элементной базе.))
4) О програмном обеспечении
К системному програмному обеспечению относятся прежде всего средства
создания програмного обеспечения, а потом средства загрузки и управления его
работой. Это различные компиляторы, прежде всего компилятор базового языка,
и редактор связей. А так-же различные загрузчики, супервизор управления па-
мятью, планировщик, средства ввода/вывода и вообще вся операционная система.
Из всего разнообразия их свойств и функций рассмотрим только то, что связано
с особенностями архитектуры.
Основными особенностями архитектуры являются сегментная организация памяти;
самоопределяемость данных как на уровне сегментов, так и отдельных значений,
и как следствие относительная независимость программы от типов и форматов
данных; аппаратная реализация элементов языка высокого уровня.
Поэтому одной из основных функций системного програмного обеспечения является
манипуляция с сегментами.
Каждый сегмент снабжается уникальным именем, под которым фигурирует в
течении всей его жизни *******
4.1 Базовый язык.
Основная функция базового языка - служить средством описания сегментов.
Компилируемая единица, например файл, может содержать описание одного или
нескольких сегментов, а так же необходимых для этого ситуаций и видов запи-
сей. Последние могут быть описаны отдельно и подключены средствами предпро-
цессора, аналогичного используемому в языке Си. Каждый сегмент снабжается
уникальным именем, под которым фигурирует в дальнейшем в течении всей его
жизни. Если имя не указано в программе явно - его генерирует компилятор.
Каждое описание состоит из заголовка и тела. Заголовок "объявляет"
сегмент, приписывает ему имя и аттрибуты (тип, размер, формат слов, или ре-
жим выполнения). Тело изображает содержимое сегмента. Массивы и записи опи-
сывают сегменты данных, процедуры - сегменты команд. (Описание специальных
сегментов здесь не рассматривается.)
Все массивы, записи, процедуры глобальны, статичесская вложенность
отсутствует. Внутри процедур могут быть локальные подпрограммы, но все они
одинаково локальны. Процедура может получить управление на единственную
точку входа - ее начало. Возможна передача параметров. Способ передачи (по
значению или по ссылке) определяется в месте вызова. Процедура может возвра-
тить произвольное количество значений (одно, несколько или ни одного) и сама
решает, что делать с переданными параметрами (удалить или оставить на стэ-
ке). Локальные переменные - только простые "автоматические". Локальную за-
пись или массив можно создать с помощью генератора, если позволяет система
управления памятью. (В младших моделях - нет.) Обращение к процедуре не
отличается от команды процессора и так-же как команда может быть снабжено
непосредственным операндом.
4.1.1 Данные.
Сегмент данных может быть описан в виде массива или записи. Массив это
последовательность одинаковых элементов, запись - разных. Доступ к элементам
массива производится с помощью индексов, а к элементам записи - по именам
полей. Массив может содержать любое число элементов, индекс может быть вы-
числен по мере надобности; размер записи фиксирован при описании ее вида,
смещения, соответствующие именам полей - тоже. Впрочем один и тот-же сегмент
можно рассматривать и как массив и как запись, независимо от того, как он
был описан.
В отличии от языка Си, в данном определяемых типов нет - только встроен-
ные, распознаваемые аппаратурой. Таковых четыре - целое, вещественное, бито-
вый набор и теговое слово. Последний тип - "невидимый" - он используется для
представления данных других типов. Не только выше перечисленных информацион-
ных, но и специальных - селектора сегмента, пустого значения, косвенного
слова.
Описываемые по мере надобности "виды записей" типами не являются. Они
определяют структуру записей, а не значений. Описание вида это перечень имен
полей и их форматов. (Если формат опущен - он будет равен формату одного
слова.) Некоторый вид может быть потомком другого - указанные в его описании
поля добавляются к полям вида-предка. Пространство имен полей общее для всех
видов, поэтому все имена должны быть уникальными.
Начальное значение сегмента данных изображается списком констант (для мас-
сива) или списком значений отдельных полей (для записи). Тип констант должен
совпадать с типом сегмента; но если изображается сегмент теговых слов, то
константы могут быть любые. В том числе "пустое" значение и селектор
сегмента. Последний изображается именем сегмента или его безымянным описа-
нием.
4.1.2 Процедуры.
Сегмент команд изображается в виде процедуры. Заголовок вводит имя и режим
выполнения, а тело состоит из описаний и предложений. Предложения транслиру-
ются непосредственно в выполняемый код, а описания вводят локальные имена,
используемые в теле процедуры. (Все именуемые ими локальные объекты локальны
в одинаковой степени.) Описываются формальные параметры, локальные перемен-
ные, метки и локальные подпрограммы.
Локальные переменные и формальные параметры процедуры образуют запись
активации. Она размещается в операционном стэке и создается явным образом
инструкцией "создать запись активации". Именам переменных (как и полей в
обычной записи) соответствуют фиксированные смещения. При описании перемен-
ных может быть использован ранее объявленный вид. (Тогда именами переменных
становятся имена полей.) При создании записи активации начальными значениями
переменных становятся данные, содержащиеся на этот момент в активной части
стэка. Перед этим можно проконтролировать (и скорректировать) их формат и
количество инструкцией "контроль записи активации". (Если формат значений не
соответствует формату переменной - он будет изменен, если значений недоста-
точно - будут добавлены "пустые", лишние значения игнорируются.) Одновремен-
но доступна только одна запись активации - последняя. Она локальна внутри
ближайшего закрытого предложения, в том смысле, что при выходе из него
разрушается. И становится доступной предыдущая. Каждое объявление вводит но-
вый список имен переменных, кроме самого первого - оно дополняет список
формальных параметров.
Метка указывает место в программе. Ей соответствует смещение в сегменте
команд. Имя локальной подпрограммы - то же самое что и метка, но указывает
на начало тела подпрограммы. Оно всегда размещается после тела основной про-
цедуры, независимо от того, где оно находится в тексте программы.
Значения, соответствующие локальным именам, всегда используются в качестве
непосредственных операндов команд, получены в "явном" виде и использованы в
вычислениях быть не могут. Поэтому "вычисляемый переход" организовать не-
возможно. (Впрочем необходимость этой конструкции весьма сомнительна.) Но (в
виду практичесской важности) можно получить ссылку на локальную переменную.
Для этого имеется специальный тип данных - "косвенное слово". С его помощью
производится передача параметров "по ссылке" (в отличии от обычного - "по
значению"), причем способ передачи параметров определяется в момент вызова.
Кроме того косвенное слово может быть использовано для обработки списков па-
раметров неопределенной длины. Для этого оно (в отличии от селектора) может
быть модефицировано, но только в том случае, если указывает значение в пре-
делах текущей записи активации.
Предложение, транслируемое непосредственно в выполняемый код, может быть
инструкцией, выражением, закрытым предложением и структурным предложением.
Предложения (и описания) разделяются с помощью "," и ";". Запятая играет как
правило чисто синтаксическую роль, а точка с запятой является инструкцией
"опустошение", очищающей активную часть операционного стэка, делающей его
пустым. Часть программы, завершаемую ";", можно назвать "оператором".
Инструкция непосредственно транслируется в одно или несколько слов
сегмента команд (и как правило соответствует одной команде процессора).
Предложения других видов эквивалентны соответствующей последовательности
инструкций (и как правило преобразуются в нее компилятором), но более
удобны, наглядны, структурны, и.т.п. Однако есть действия, реализуемые толь-
ко в виде инструкций. Это безусловный переход, создаение записи активации,
явные манипуляции с вершиной операционного стэка. Инструкция изображается
именем (знаком операции) и может содержать один или несколько непосредствен-
ных операндов. (Исключением является константа - состоит из одного не-
посредственного операнда.)
Выражение устроено вполне традиционно. Оно состоит из констант, обращений
к переменным, сегментам и функциям, операций и круглых скобок. При трансля-
ции преобразуется в обратную польскую запись. Скобки в выражении играют
чисто синтаксическую роль. Результат вычисления выражения - значение, причем
только одно. Оно остается на вершине операционного стэка, в остальном его
состояние не меняется. Набор операций фиксирован в языке (средств его расши-
рения пока не предполагается), процедуры, используемые в качестве функций,
должны "хорошо себя вести" - возвращать ровно одно значение и не изменять
состояния стэка.
Закрытое предложение это часть программы, являющаяся областью существова-
ния локальных объектов - записей активации, ловушек на ситуации, локальных
сегментов. Если оно ограничено операторными скобками, то является еще и
областью действия введенных внутри него имен переменных (но не меток). В на-
чале закрытого предложения в управляющий стэк помещается, а в конце извлека-
ется некоторая запись. (Что при этом происходит - см. п*** описание стэково-
го механизма.) Закрытым предложением являются "круглые скобки" и некоторые
структурные предложения - тело процедуры, блок, блочный цикл. (Впрочем то-
го-же эффекта можно добиться используя соответствующие инструкции.)
Структурные предложения предназначены для управления порядком действий.
Это тело процедуры, блок, разные виды циклов, условное и выбирающее предло-
жения. Устройство их традиционно. Реализуются они с помощью неявных меток и
соответствующих инструкций (условного, безусловного, множественного перехо-
да; возврата из подпрограммы; инструкций "начало блока", "повторить", "вы-
ход"). Еще к структурным средствам управления порядком действий относятся
вызов процедуры и структурный переход. Вызов процедуры в простейшем случае
(прямой, без явных параметров) не отличим от инструкции - состоит из одного
имени (имени сегмента или метки). Более того, он может сопровождаться не-
посредственными операндами. Косвенный вызов предполагает, что селектор
сегмента команд будет сперва "вычислен". (Косвенный вызов локальной
подпрограммы невозможен.) Явная передача параметров выглядит обычным образом
- список в круглых скобках после обращения к процедуре. А фактически проце-
дуре "достается" вся активная часть стэка.
Структурный переход состоит из двух фаз - установки ловушки и собственно
перехода. Последний происходит при возникновении и "распространении" ситуа-
ции. Если ситуация не возникнет (естественным образом или будет создана
искуственно) переход не произойдет. Если ситуация возникла при отсутствии
ловушек на нее - для процесса это кончается фатально. Ловушка устанавлива-
ется специальной конструкцией, в которой указывается тип ситуации и процеду-
ра реакции на нее. (Последняя может быть как глобальной так и локальной или
вообще отсутствовать, тогда реакция будет нулевой.) Порождение ситуации про-
изводится специальной операцией и так-же как обращение к подпрограмме может
сопровождаться списком параметров. На настоящий момент остается открытым
вопрос: разрешить ли "вычисление" типа ситуации. Если да, то либо надо вво-
дить еще один специальный тип данных, либо использовать целые числа. Целесо-
образность того и другого под вопросом. Поэтому будем считать, что тип ситу-
ации - внутреннее значение, получить которое в явном виде нельзя. Обознача-
ется именами, введенными в описании ситуации. Состоит из двух частей -
старшен, характеризующей общую причину возникновения ситуации, и младшей,
конкретизирующей ее.
4.1.3 Синтаксис.
Синтаксис базового языка может в значительной степени быть позаимствован у
языка Си. Рассмотрим один из вариантов, в основном на примерах.
/* Это коментарий. Он устроен так-же как в языке Си. */
// Это тоже коментарий. Он продолжается до конца строки.
1, 1.0, 01 // Это константы трех основных типов.
(ф3)1, (вещ)1, (набор5)1 // то же самое, с явным указанием типа (формата)
Тип простой константы распознается по ее внешнему виду, но может быть указан
явно. Символьные константы считаются битовыми наборами (2) и устроены в
точности как в языке Си. Имена (индентификаторы) как обычно состоят из букв
цифр подчеркивания надчеркивания и кочерги, и должны начинаться с буквы.
Смысл каждого используемого в программе имени должен быть известен компиля-
тору. Это может быть ключевое слово, имя инструкции (они известны заранее),
имя сегмента, вида записи, поля записи, ситуации (описываются снаружи) ло-
кальной переменной, метки (описываются внутри процедуры). Использовать рань-
ше, чем она описана, можно только метку.
Глобальное описание начинается ключевым словом ("вид", "проц", "массив",
"запись" и.т.д); далее может быть объявляемое имя; параметры (например длина
и тип сегмента) в квадратных скобках (если параметров более одного - разде-
ляются двоеточиями); имя вида (вида-предка) через "::"; список имен полей
(или переменных) и их форматов в круглых скобках; и в конце тело вводимого
объекта в фигурных скобках. Тело может отделяться от заголовка символом "=",
но не обязательно.
вид ааа(а,б,ц); // описание вида записи "ааа"
вид ббб:ааа(д,е:ф4); // вид "ббб", потомок предыдущего
массив ццц[цел4:7]; // сегмент целых чисел из семи элементов
массив ддд={ 3, (пусто), массив[17:вещ], ддд };
/* сегмент теговых слов из четырех элементов, включает целое число,
пустое значение, селектор безымянного сегмента вещественных чисел
(из 17 элементов) и (для смеха) свой собственный селектор */
запись еее::ааа; // запись вида "ааа" без инициализации.
запись жжж::ааа(ф; г:ф10, х)={ а=0, г=0.0, х=(пусто) };
/* запись того-же вида, но с дополнительными полями и с инициализацией */
ситуац нетДенег(кончились, украли, потерял, забыл); // ситуация
проц ззз(x,y,z:ф11){ кза, сза, (x+y)*(z+2) }; // процедура.
Переменные описываются почти так-же как и виды - "перем" и список имен пере-
менных и их форматов в скобках; описание локальной подпрограммы вылядит
так-же как и описание глобальной процедуры, но вложено в нее; описание метки
- ее имя и ":" - в том месте, которое она отмечает. Предложения и описания
разделяются "," и ";". Инструкция состоит из имени (как правило совпаданет с
названием команды) и возможно непосредственного операнда. Он отделяется зна-
ком "#". Обращение к переменной - ее имя. Прямое обращение к процедуре - то-
же. Обращение к сегменту данных - его имя (или выражение, вычисляющее се-
лектор) и индексное выражение в квадратных скобках или имя поля через точку.
Выражение состоит из "термов" и знаков операций. Термом может быть
константа, обращение к переменной, функции, сегменту данных и выражение в
круглых скобках. Структурные предложения состоят из ключевых слов, обознача-
ющих их части, круглых скобок, заключающих необходимые выражения и фигурных
- обозначающих границы его частей.
перем(а, б:ф4; ц, д; е: ф12) // описание локальных переменных
метка2: /* метка */ бп #метка2 /* инструкция перехода к метке */
блок{ ... } // блок
блц(...){ ... выход .... повторить ... } // блочный цикл
цикл(...){ ..... } // цикл с предусловием
{ .... }цикл(...) // цикл с постусловием
если(...){ .... } иначе{ ..... } // условное предложение
выб(...){ 1: .... 2: .... 3: .... иначе: .... } // выбирающее предложение
возвр // инструкция возврата из подпрограммы.
д=3.1415926; // присваивание
ззз(1, &д, 2) // обращение к процедуре
при нетДенег:ззз // ловушка на ситуацию
нетДенег.забыл!!(1, &д, 2) // порождение ситуации
Все входящие в выражения операции обозначаются одним или двумя спецсимволами.
Некоторые используются как у бинарном, так и в унарном вариантах (в зависи-
мости от количества окружающих знак операции термов). Старшинство операций
как в Си. Каждая операция берет со стэка один или два операнда и оставляет
ровно один результат.
+, -, *, /, % // арифметические операции
:+, :-, :^, ^, <<, >>, :/, :*(...) // побитовые операции:
<, <=, >, >=, ==, != // операции сравнения
&, |, !, ~ // логичесские операции
= // присваивание
++, -- // инкремент и декремент (применим только к переменным)
-, &, * // унарные операции, обозначаемые которых совпадает с бинарными
(цел), (вещ10), (набор), (ф5) // явное преобразование типа и формата
Арифметические операции - обычные; побитовые - установка, сброс, инверсия
бит по маске (или, не-и, искл. или), инверсия, сдвиги, разрезание и объеди-
нение битовых наборов; операции сравнения - обычные; логичесские операции
"и" (min), "или" (max), четкая и нечеткая инверсии (четкая "!" эквивалентна
">=0", для наборов - "==0"; нечеткая "~" - смена знака, для наборов - поби-
товая инверсия); унарные операции - смена знака, взятие адреса переменной
или получение селектора процедуры, косвенный вызов процедуры.
4.2 Форматы програмного обеспечения.
Програмное обеспечение может существовать в нескольких формах. Самая
первая из них - это "исходный текст" - действительно некоторый текст, напи-
санный с соблюдением грамматических правил некоторого алгоритмического язы-
ка. В таком виде программа доступна людям, но не машине. Хотя и может быть
"выполнена" с помощью соответствующего интерпретатора.
Результатом работы компилятора является образ программы в объектном форма-
те. Он должен включать таблицу имен объектов, таблицу форматов переменных и
полей записей, таблицу имен ситуаций, ну и собственно образ сегментов, со
ссылками на эти таблицы. (Таблица меток предполагается ненужной.) Объектный
формат сохраняет почти всю информацию, содержавшуюся в исходной программе и
может быть использован наравне с ней для переноса програмного обеспечения,
или восстановлен до исходного текста на базовом языке. (Утраченными окажутся
только локальные имена и коментарии.)
Выполняемый формат это результат настройки на конкретную модель процессо-
ра, его систему команд, а так-же операционную систему и програмное окруже-
ние. В нем отсутствуют таблицы форматов и ситуаций (для ситуаций и смещений
установлены конкретные значения). Установлены конкретные коды встроенных ко-
манд или селекторы подпрограмм их заменяющих, а так-же селекторы резидентных
сегментов операционной системы. Их имена из таблицы имен удалены. Конкретные
значения остальных селекторов устаналиваются при загрузке.
Образ памяти это состояние программы в момент ее выполнения. Установлены
конкретные значения всех констант и селекторов.
Выполняемая программа собирается с помощью редактора связей из модулей,
полученных после трансляции ее частей (а так-же стандартных, хранящихся в
библиотеках). Программы, предназначеные для прошивки в ПЗУ, выдаются в виде
образа памяти, остальные в объектном или выполняемом формате.
4.3 Управление памятью.
Узким местом настоящей архитектуры является недостаточно большое простран-
ство селекторов сегментов. В "базовой" модели их всего около 4000. Для не
слишком больших систем это вполне приемлемо. Для очень серьезных задач сле-
дует использовать "старшие" модели, где длинна селектора достаточно велика.
Однако с дефицитом селекторов (а заодно и оперативной памяти) можно вполне
успешно бороться, используя различные меры.
Средство номер один - позднее связывание. Конкретные селекторы назначаются
сегментам на этапе загрузки. Средство номер два - свопинг. Сегменты, не по-
мещающиеся в оперативной памяти выгружаются во внешнюю, а в случае обращения
к ним подгружаются обратно. ("Основной" режим адресации именно для этого и
предназначен.) При выборе сегментов для выгрузки следует выбирать такие, ко-
торые принадлежат процессам, находящимся в приостановленном состоянии. При
более высоких требованиях к объему програмного обеспечения (и пониженных к
скорости реакции на внешние события) следует использовать более дорогостоя-
щие средства.
Во-первых следует ввести понятие "задача". Задача это совокупность процес-
сов, выполняющих общую работу. (В заголовке процесса возможно придется выде-
лить слово для хранения номера задачи, к которой он принадлежит.) При-
надлежность процессов задачам следует учитывать при предоставлении процессо-
ра в режиме разделения времени, при выгрузке в свопинг и окончательном уда-
лении сегментов из памяти (в случае окончания соответствующей задачи).
Во-вторых следует вести системную таблицу имен сегментов. Это позволит при
выгрузке сегмента освобождать его селектор, производя операцию обратную ре-
дактированию связей. А выгруженные сегменты хранить в формате, подобном
объектному. Это возможно (и имент смысл) только при одновременной выгрузке
всех взаимосвязаных сегментов (то есть всей задачи). Так как только в этом
случае можно быть уверенным, что больше ссылок на данный сегмент нет.
И наконец в третьих для каждой задачи можно организовать собственное
пространство селекторов. Это требует аппаратной поддержки: таблицу сегментов
надо разбить на несколько (4, 8 иди даже 16) частей - страниц, размещаемых в
отдельных сегментах. В заголовке каждого процесса выделить место для хране-
ния соответствующего числа указателей на эти подтаблицы. При переключении
процессов аппаратно загружать их во внутренние регистры процессора. (Нулевую
страницу, очевидно, перезагружать нельзя.) Это позволит при необходимости
организовать собственное пространство селекторов для каждого процесса, для
группы процессов, или общее для всех. Кроме того селекторы можно размещать
по страницам в зависимости от функционального назначения сегментов.
5) Базовая модель.
Приводятся организация данных и примерный набор команд базовой модели.
Первоначальная реализация базовой модели предполагается на базе общей шины
микро-ЭВМ семейства Электроника-60 в однопроцессорном варианте. Предполага-
ется использовать имеющийся у этого семейства набор внешних устройств.
5.1 Общие сведения об организации данных.
Запоминающих сред две - оперативная память и пространство регистров
внешних устройств. Размер физического слова - 16 разрядов. Теговое слово
совпадает с физическим. Длина его информационной части 12 разрядов, и 4
разряда - тег. Длина виртуального слова кратна четырем разрядам ("т" -
тетраде) и может быть произвольной, от 1 до 16 "т" (4 - 64 бита).
Сегмент целиком размещается в ОЗУ и состоит из служебной части и информа-
ционной. Служебная часть - два физических слова. В первом тип сегмента и до-
полнительная информация, зависящая от типа. Во втором - максимальное смеще-
ние. Используется для контроля выхода за границы сегмента. Максимальный
размер сегмента - не более 64К виртуальных слов. "Физические" сегменты
(изображающие запоминающие среды) и сегменты в пространстве внешних
устройств служебной части не имеют. Выход за границы сегмента для них не
проверяется - тот-же самый эффект дает ошибка обращения к шине. Сегмент при-
надлежит к одному из четырех типов: (а) сегмент данных, (б) сегмент команд,
(в) сегмент управляющего стэка и (г) сегмент специального типа. Первые два
состоят из виртуальных слов, вторые - из физических.
Используются начальный и основной режимы адресации. В начальном режиме се-
лектор содержит физический адрес начала сегмента, сдвинутый на два разряда.
Т.е. сегмент может начинаться с каждого четвертого физического слова.
5.2 Сегменты.
Сегмент данных состоит из виртуальных слов, тип и размер которых указан в
его служебной части: 2 бита - тип сегмента; 2 бита - тип слова (целое, ве-
щественное, битовый набор, теговое слово); 4 бита - формат. Остальные 8 бит
первого слова не задействованы. (В дальнейшем предполагается добавить их ко
второму - размеру сегмента.)
Сегмент команд - формат слов фиксирован - 12 разрядов. Первое слово слу-
жебной части при активизации сегмента загружается в регистр состояния про-
цессора. Оно содержит: 2 бита - тип сегмента; 1 бит - режим адресации; 1 бит
- привилигированность; 2 бита - непосредственные операнды (нет, 1 слово, 2
слова, много слов - со счетчиком в первом); 2 бита - признаки разрешения
прерывания. Остальные 8 бит зарезервированы под прочие признаки.
Сегмент управляющего стэка состоит из физичесских слов. Первое слово заго-
ловка содержит: 2 бита - тип сегмента; 12 бит - номер процесса; 1 бит -
признак наличия временного процесса; 1 бит - признак остановки перед семафо-
ром. Хранит информацию в виде записей стандартного формата. Последнее слово
каждой записи содержит тип этой записи. Первая запись - заголовок процесса.
Сегмент специального типа состоит из физических слов, хранит служебную
информацию. Предназначен для расширения архитектуры. Его формат на данном
этапе не определяется.
5.3 Таблица сегментов.
Таблица сегментов используется при основном режиме адресации для обращения
к сегментам. На части не разбивается. Состоит из дескрипторов сегментов - 64
разрядных структур фиксированного формата. Дескриптор включает: 20 бит -
адрес начала сегмента (без двух младших разрядов); 16 бит - количество
места, занимаемого сегментом (по 4 физических слова); 12 бит - номер процес-
са-хозяина; 4 бита - признаки. Остальные 12 бит не задействованы. Признаки:
2 бита - местонахождение/тип сегмента (обычный, "физический", в пространстве
внешних усторойств, выгружен); 1 бит - разрешение присвоения сегмента про-
цессом; 1 бит - сегмент подлежит освобождению (был использован как локаль-
ный).
5.4 Записи в управляющем стэке.
Заголовок процесса. Содержит: (1) селектор сегмента операционного стэка;
(2) пространство для сохранения внутренних регистров процессора (5 слов);
(3) ссылка на паспорт временного процесса; (4) ссылка на сегмент, являющийся
семафором; (5) дополнительные слова (3 слова); (6) признак типа записи.
Адрес возврата из подпрограммы. Содержит: (1) селектор активного сегмента
команд; (2) смещение; (3) слово состояния процессора; (4) признак типа запи-
си. Эта-же запись используется при приостановке процесса.
Фиктивный адрес возврата. Состоит только из признака типа записи. Помеща-
ется в стэк при передаче управления подпрограмме реакции на ситуацию. При
извлечении приводит процессор в состояние, в котором кроме адреса возврата
ищется запись с границами блока.
Запись границ блока. Содержит: (1) границы блока (2 слова); (2) слово
состояния процессора; (3) признак типа записи.
Указатели дна и базы. Обе записи почти одинаковы. Содиржат тип записи и
значение соответствующего регистра. Указатель базы - еще и размер записи
активации.
Ловушка на ситуацию. Содержит: (1) тип ситуации; (2) указатель реакции;
(3) признак типа записи. Указатель реакции - слово с тегом. Может содержать
селектор сегмента команда, целое число - смещение в текущем сегменте, пустое
значение - нулевая реакция.
Временный заголовок процесса. Устроен в точности так-же, как и постоянный.
Только вместо селектора сегмента операционного стэка - номер этого процесса.
Локальный объект. Состоит из селектора сегмента и признака типа записи.
Предназначен для уничтожения локальных сегментов при выходе из области их
существования. При извлечении этой записи из управляющего стэка, в
дескрипторе оного сегмента устанавливается признак, указывающий, что сегмент
подлежит освобождению.
5.5 Типы данных и их представление.
Имеются информационные и служебные типы данных. Информационые могут иметь
произвольный формат, служебные - фиксированый (одно слово). Информационные
типы: целое число, вещественое число, битовый набор, пустое значение. Специ-
альные: индекс (целое без знака), начальный селектор, основной селектор,
косвенное слово.
В сегменте теговых слов данные представляются последовательностью из одно-
го или более теговых слов. При этом используются теги: "начало", "продолже-
ние", "целое", "длинное целое", "набор", "длинный набор", "вещественное",
"индекс", "косвенное слово", "начальный селектор", "основной селектор",
"пусто". Тег "начало" начинает, а тег "продолжение" продолжает последова-
тельность из нескольких слов, которая оканчивается одним из тегов: "длинное
целое", "длинный набор", "вещественное". В таком виде представляются значе-
ния соответствующих типов форматом более 3т. Они участвуют во всех операциях
как единое целое.
Пустое значение тоже способно образовывать длинные многословные значения,
для этого используется содержимое его информационной части.
В дальнейшем предполагается ввести тег "составное значение" для объедине-
ния нескольких простых значений в одно сложное. Целесообразность этого рас-
сматривается.
5.6 Система команд.
Приводистя примерный перечень команд базовой модели. В качестве пояснений
изображается состояние стэка до и после операции. (Например А, Б -> Б, А.)
Если надо указать положение локального дна, то в этом месте пишется слово
"дно".
5.6.1 Реорганизация вершины стэка.
дублирование
(дб): А -> А,А
стирание
(оч): А ->
(очн): n,А1...Аn,An+1 -> An+1
(очд): А...Б,дно -> дно - операция "опустошение" - ";".
обмен
(об): А,Б -> Б,А
(об3): А1,А2,А3 -> А2,А3,А1
(обд): А,Б...В,дно -> Б...В,А,дно
(обп): n,A1,A2...An -> A2...An,A1
манипуляции с локальным дном
(илд): A1...An,дно -> n,А1...Аn,дно
(улд): А1...Аn,дно -> дно, A1...An - операция "(".
(улдп): n,А1...Аn,Аn+1...Аm,дно -> А1...Аn,дно,Аn+1...
(влд): Б1...Бm,дно,А1...Аn -> Б1...Бm,А1...Аn,дно - операция ")".
Во всех случаях "n" должно быть меньше или равно текущей глубине лок. дна.
5.6.2 Преобразование типов и форматов.
форматов
(иф): А -> f, A - определить формат
(уф): А -> А' (с непосредственным операндом) - "(ф*)"
(уфп): f,А -> А'
типов.
(утц): А -> А' - в целое. "(цел)"
(ути): А -> А' - в индекс (беззнаковое целое)
(утн): А -> А' - в битовый набор "(набор)"
(утв): А -> А' - в вещественное. "(вещ)"
(ут0): А -> А' - в "пустое" значение
универсальные.
(итф): А -> tf, А - опеределить тип и формат
(утф): А -> А' - (с непосредственным операндом)
(утфп): tf, А -> А'
дополнительные
(мвещ): Ц1,Ц2 -> В
(двещ): В -> Ц1,Ц2
Собирают и разбирают вещественное число на два целых - мантису и порядок.
5.6.3 Ввод констант.
Помещают на стэк константу - фиксированную, или заданную непоср. операндом.
(кн00): - пустое значение
(кн0): - целое 0
(кн1): - целое 1
(кн11): - целое -1
(кнн): - короткий битовый набор
(кннд): - длинный битовый набор (2 теговых слова)
(кнц): - короткое целое
(кнцд): - длинное целое
(кни): - короткое целое без знака
(кнв): - вещественное
(кнс): - селектор сегмента
(кну): - константа любого типа и формата
5.6.4 Арифметико-логические команды.
Побитовые операции
(очб): - очистка, все биты сбрасываются в 0.
(инб): - инверсия битов "^"
(бу0): - установка в 0 по маске (эквивалентна "не-и") ":-"
(бу1): - установка в 1 по маске (эквивалентна "или") ":+"
(буи): - инверсия по маске (эквивалентна "искл. или") ":^"
(бсп): n,A -> A1,A' отрезание и присоединение n разрядов к операнду А
(бсл): n,А1,А -> А'
Недостающие разряды одного из операндов считаются нулевыми, старшие нулевые
разряды результата могут быть отброшены.
Арифметические операции.
(сл): - Сложение "+"
(выч): - Вычитание "-"
(умн): - Умножение "*"
(дел): - Деление "/"
(дело): А,Б -> Ч,О - Деление с остатком "%"
(сзн): - Смена знака (унарный минус) "-"
(абс) - Сброс знака (абсолютное значение)
Результат преобразуется к старшему типу и формату.
Логические операции
(иии): - и "&" (эквивалентно "min")
(или): - или "|" (эквивалентно "max")
(не): - "четкое" не "!" (экв. сравнению с нулем)
(нне): - "нечеткое" не "~" (экв. инверсии или смене знака.)
Значение "ложь" - нулевой битовый набор, пустое значение, числа меньше или
равные нулю. Все остальное - "правда".
Операции сравнения.
(сбл): - Больше ">"
(сбр): - Больше равно ">="
(срв): - Равно "=="
(сб): - Побитовое сравнение (экв. побитовой "и")
(стбл): - Старшинство типов
(стрв): - Равенство типов
(пти): - тип - один из информационных
(птк): - тип операнда - косвенное слово
5.6.5 Обращение к переменным и памяти.
Обращение к произвольным сегментам.
(чт): I,S -> А. - Чтение "[ ... ]", ".ИмяПоля"
(зп): I,S,А -> - Запись "[ ... ]=" ".ИмяПоля="
"I" - индекс - целое число; "S" - указатель сегмента - селектор или
косвенное слово для обращения к записи активации.
Обращение к переменным
(чтп): -> А - чтение
(зпп): А -> - запись
(адрп): -> К Создание косвенного слова "&"
(инк): - инкремент и декремент - изменение содержимого переменной на 1
(дек): при переходе через 0 возникает ситуация.
5.6.6 управление порядком выполнения действий.
Переходы.
(бп): - безусловный.
(уп): Л -> - условный
(мнп): Ц -> - множественный
(пп): - переход к подпрограмме внутрисегментный
(ппк): S -> - переход к подпрограмме косвенный
(вп): - возврат из подпрограммы.
(ппс): - спецпереход - по селектору другого режима.
организация блочного цикла
(блц): начало блочного цикла
(вых): "выход"
(повт): "повторить"
Механизм ситуаций.
(ловг): Т, S -> - Установить глобальную ловушку
(ловл): T -> - Установить локальную ловушку
(сит): Т -> - создать ситуацию (запустить структурный переход)
(жд): - ожидать возникновения ситуации
прерывания.
(прр): - командное прерывание по фиксированному вектору.
5.6.7 Прочие команды.
Признаки в слове состояния процессора.
Эта группа команд не рассматривается - на настоящем этапе не определено
устройство слова состояния процессора. Оно автоматически загружается и
сохраняется при каждом вызове подпрограммы. Дополнительно предполагается
ввести команды чтения и записи этого слова.
Ключевая защита сегментов.
(ссо): S -> - Сделать сегмент общедоступным.
(ссс): S -> - Присвоить сегмент текущему процессу
(сса): S -> - Присвоить сегмент (закрытие семафора) неделимая операция.
(сср): S -> - Разрешить присвоение сегмента (открытие семафора)
(ссз): S -> - Запретить --//--
(ссп): S -> Л - Проверить --//--
Управление процессором.
Команды "стоп", "рестарт", и т.п. не вводятся - предполагается подобные
действия над процессором предполагается производить с помощью управляющих
регистров процессора, доступных, как и регистры внешних устройств, со сторо-
ны общей шины.
5.7 Младшая модель.
Младшая модель это сокращенная версия базовой. Ее основные отличия:
а) Длина физического слова - 12 разрядов. Концепции виртуального слова не
вводится - все сегменыт состоят из физических слов. Теговых слов нет.
Единственный тип данных - 12и разрядный битовый набор.
б) используется только начальный режим адресации. Селектор сегмента
представляет собой физический адрес без двух младших разрядов. (Которые по-
лагаются равными нулю.) Объем ОЗУ - 16К слов.
в) Служебная часть сегмента состоит из одного слова. Младшие два бита опре-
деляют тип сегмента, а оставшиеся 10 разрядов - его длину (тоже без двух
младших разрядов). Таким образом начало и размер указываются с точностью до
четырех слов.
Служебная часть сегмента команд состоит из двух слов. Второе загружается в
слово состояния процессора.
г) Отличия в системе команд: нет преобразования типов и форматов; сокращен
набор команд ввода констант; набор арифметичесских, побитовых и команд ре-
организации вершины стэка может быть расширен операциями, работающими с па-
рой и тройкой слов; в арифметических и побитовых командах используется скры-
тый регистр "второе слово результата"; набор операций сравнения расширен для
работы со знаковыми и беззнаковыми числами в дополнительном коде; команд
использующих принадлежность сегмента процессу (как и самой принадлежности)
нет. Возможно введение отдельных команд, работающих с числами с плавающей
запятой, занимающих три слова.
6) Заключение.
Приведенное в настоящей работе описание архитектуры является предваритель-
ным и отнють не исчерпывающим. Хотя с точки зрения автора оно содержит
достаточно сведений, чтобы можно было приступить к его реализации. Реализа-
ция предполагается в четыре этапа: Первый - написание эмулятора, работающего
под достаточно развитой операционной системой; написание и отладка с его по-
мощью базового програмного обеспечения. Второй - "полная" эмуляция -
программа-эмулятор зашивается в ПЗУ процессора, шина которого будет исполь-
зована в первоначальной реализации (электроника 60.1 или подобный ему). Тре-
тий - создание процессора подключаемого к этой шине. Четвертый - окончатель-
ная реализация - разработка и реализация собственного шинного протокола;
создание собственного набора внешних устройств; доработка процессора и
програмного обеспечения.
Настоящая архитектура (по крайней мере для автора) интересна с двух точек
зрения: Во-первых это повышение семантичесского уровня у машины, которая (в
отличии от Эльбруса) изначально проэктировалась как "маленькая". А во-вторых
это промежуточная ступень на пути к архитектуре пятого поколения. Она описа-
на в следующей (а по времени написания - предыдущей) работе, интересна тем,
что ориентирована аж на объектные языки и позволяет строить ну оченьмно-
гопроцессорные машины. Что (опять-же по мнению автора) может явиться предпо-
сылкой чуть-ли не очередной революции в вычислительной технике.