Основы AS/400
Шрифт:
Наилучший целевой компьютер для компиляторов ILE — стековая машина, поэтому MI был расширен для поддержки стеков. Стек — набор данных, хранящихся последовательно. Первый помещенный в стек элемент называется его дном, последний — вершиной. Для работы со стеком используются команды без явного указания операндов, которые определяются путем извлечения из стека двух верхних элементов. В противоположность этому, команды ОРМ имеют два операнда, заданных непосредственно в команде. Для стековой машины операция задается после операндов. Такая форма записи называется постфиксной или обратной польской в честь математика Лукашевича (J. Lukasiewicz), исследовавшего ее свойства [ 37 ] .
37
Правильней было
Интересно, что архитектура, разработанная в 1972 году, имела аналогичную поддержку стека. В то время многие полагали, что блочно-структурированные языки, такие как PL/1, станут очень популярными. Но они так и не вытеснили RPG и Cobol, так что стек был временно отвергнут. Теперь, с появлением таких языков как С, мы снова вернулись к нему.
Рисунок 4.7 Команды и ODT
Шаблон программы состоит из нескольких частей. Шаблон программы ОРМ содержит заголовок, последовательность команд MI, пользовательские данные и структуру под названием таблица определения объектов ODT (object definition table). Команды и ODT представлены на рисунке 4.7. Последовательность команд на рисунке содержит пример команды MI. Использована классическая команда OPM с тремя операндами —арифметическое сложение. Она состоит из кода операции, за которым следуют три значения, используемые для поиска трех операндов. Каждое из них является индексом в ODT. Показанная на рисунке команда запрашивает сложение операнда 6 с операндом 2 и помещение суммы в операнд 3.
ODT состоит из двух компонентов. Первая — ODV (ODT Direction Vector) — содержит по одному элементу для каждого операнда программы. Все элементы имеют одинаковую длину, так что значение из последовательности команд может использоваться как индекс в ODV. Элементы ODV описывают операнды. В нашем примере, операнды 6 и 3 — это двоичные числа длиной 2 байта, а операнд 2 — константа. Константы и другие типы операндов могут иметь переменную длину, что задает необходимость второго компонента ODT. OES (ODT Entry String) содержит операнды переменной длины, не умещающиеся в ODV. Содержимое поля ODV указывает на начало цепочки в OES. В нашем примере операнд 2 представляет собой константу 1253.
Пример иллюстрирует несколько характеристик команд MI модели ОРМ. Во-первых — это команда арифметического сложения. Это не команда двоичного или десятичного сложения, или сложения с плавающей запятой; она универсальна. Формат операндов команды определяется в ODT. В нашем примере используются двоичные целые операнды, но они могли бы иметь любой числовой формат. За генерацию необходимых преобразований отвечает транслятор.
Во-вторых, из примера видно, что ОРМ MI — неисполняемый интерфейс. Обратите внимание, что ни с операндом 3, ни с операндом 6 не связаны значения. Элемент ODV эквивалентен объявлению переменной. Память для переменной не выделена, так что транслятор обязан завершить компиляцию и назначить переменным регистры или области памяти.
И, наконец, в примере показана обычная вычислительная команда. Команда, работающая с объектом, имела бы аналогичный формат, но в ODT было бы указано, как найти объект (детали адресации объектов будут рассмотрены в главе 5).
Рисунок 4.8 Формат команд MI
На рисунке 4.8 показан формат команд ОРМ MI в потоке команд. Команда состоит из кода операции, необязательного расширения кода операции, а также нуля или более операндов. MI проектировался в расчете на последующие расширения, так что формат команды допускает увеличение числа команд и операндов. Код операции и его расширение представляют собой 16-разрядные поля. Поле операнда, используемое как индекс в ODV, первоначально на System/38 имело длину 16 бит, но затем было расширено до 24 бит. Это
означает, что в программе может быть до 16 миллионов (224) разных операндов, и эта цифра может быть увеличена.Экономия памяти не была слишком важна для шаблона программы. Например, команда арифметического сложения заняла бы 2 байта для кода операции, 2 байта — для расширения кода операции и 9 байтов — для операндов. Получается 13 байтов, и мы еще не учли пространство для операндов в ODT. Не удивительно, что пользователи System/36 были недовольны объемом дискового пространства, занимаемого программами.
В таблице 4.14 показано назначение битов кода операции MI. Бит 3 задает вычислительный или невычислительный формат команды. Во втором случае функция, которая должна быть выполнена, закодирована в битах 5-15 кода операции. Функция, выполняемая вычислительной командой, задается битами 8-15. В этом случае, как в примере с арифметическим сложением, биты 5-7 содержат дополнительную информацию о команде.
Бит 6 вычислительного формата указывает, должно ли производиться округление. Обычно, округление характерно для арифметики с плавающей запятой, однако, проектировщики MI имели в виду не это. AS/400 — это машина для коммерческих расчетов, и округление, используемое в MI — это десятичное округление. Десятичные данные рассматриваются как данные с плавающей десятичной запятой.
Бит 7 указывает на сокращенную форму команды, что также имеет смысл только для вычислительных команд. В нашем примере арифметического сложения участвуют три операнда. Два из них складываются, и результат помещается в третий, то есть два первых операнда не изменяются. Сокращенная команда также складывает первые два операнда, но результат помещается в первый операнд. Таким образом, сокращенная команда использует формат только с двумя операндами.
Таблица 4.1 Назначение битов кода операции
Наконец, в вычислительном формате имеются два бита, описывающих расширение кода операции. Биты 4 и 5 определяют наличие расширения и если таковое присутствует — способ его использования. Это требует более подробного объяснения.
Расширение кода операции MI занимает следующие 16 бит команды и имеет две формы: опция перехода и опция индикации. Наличие расширения задается установкой бита 4, а в положительном случае разряд 5 выбирает опцию перехода или индикации.
В случае использования опции перехода расширение кода операции делится на четыре 4-разрядных поля. Каждое из них применяется для определения возможностей перехода для данной команды. В процессе исполнения любой вычислительной команды MI возможен условный переход. Другими словами, в зависимости от результатов вычисления следующая команда MI может быть выбрана из некоторого другого места последовательности команд.
Рассмотрим первое 4-разрядное поле расширения. Значение 1 (двоичное 0001) в этом поле означает переход в том случае, если в результате вычисления получено положительное число. Значение 2 (двоичное 0010) задает переход при отрицательном значении результата. Если же поле имеет значение 4 (двоичное 0100), то переход выполняется при результате равном 0. Имеются также значения для перехода при ненулевом, неположительном, неотрицательном и не ненулевом результате. Кроме того, та же самая комбинация битов может иметь разный смысл для разных типов команд. Например, команда сравнения интерпретирует биты иначе, чем команда сложения.
Если условие перехода, заданное первым 4-разрядным полем выполнено, то цель перехода может быть найдена за последним операндом команды. Если условие перехода не выполнено, то будет исполняться следующая команда по порядку. Такие возможности команд приводят к увеличению их длины.
Так как каждое из четырех 4-разрядных полей расширения используется для задания условия перехода, то каждая вычислительная команда может содержать до
четырех условий и до четырех целей перехода. Если нужно менее четырех условий, то значение 0 задает отсутствие перехода.