| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В серии книг Искусство программирования Д. Кнута для иллюстрации алгоритмов и умений, необходимых каждому серьёзному программисту, автор использует виртуальный компьютер MIX (вместе с соответствующим набором двоичных инструкций). Как для любого реального компьютера, существует символический язык ассемблера, на котором можно программировать MIX -- язык ассемблера MIX, MIX assembly language, сокращённо MIXAL. В следующих подразделах вы найдёте учебник, который даст вам основы архитектуры MIX и научит программировать MIX на языке MIXAL.
компьютера MIX.
2.1 Компьютер MIX Архитектура и набор инструкций
2.2 MIXAL Язык ассемблера MIX.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В этом разделе вы найдёте описание компьютера MIX, его компонентов и набора инструкций.
2.1.1 Архитектура MIX 2.1.2 Набор инструкций MIX
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Основной единицей информации в компьютере MIX является байт, в котором хранится положительное значение в диапазоне от 0 до 63. Имейте в виду, что байт MIX может быть представлен шестью битами, а не восемью, как регулярный байт. Если иное не оговорено специально, слово байт будет обозначать 6-битный байт MIX.
Слово MIX определяется как набор из пяти байтов и знака. Байты слова нумеруются от 1 до 5, первым является старший байт. Знак обозначается индексом 0. Графически,
----------------------------------------------- | 0 | 1 | 2 | 3 | 4 | 5 | ----------------------------------------------- | +/- | байт | байт | байт | байт | байт | ----------------------------------------------- |
Вы можете ссылаться на часть слова, используя спецификацию поля
(fspec) в виде: "(L:R)", где L обозначает
первый байт, а R -- последний байт поля. Когда L равно нулю,
поле включает знак слова. Спецификация может также быть представлена
одним числом F, вычисляемым как F = 8*L + R (так, спецификация
`(1:3)', обозначающая первые три байта слова, представляется числом 11).
Компьютер MIX сохраняет информацию в регистрах, хранящих либо слово, либо два байта и знак (см. ниже), и в ячейках памяти, каждая из которых содержит слово. Если быть точным, компьютер MIX имеет 4000 ячеек памяти с адресами от 0 до 3999 (т.е., для адресации ячейки памяти достаточно двух байтов) и следующие регистры:
rA
rX
rJ
rI1, rI2, rI3, rI4, rI5, rI6
Кроме того, компьютер MIX содержит:
un,
где n пробегает значения от 0 до 20. В определении Кнута,
устройства от u0 до u7 -- носители на магнитной ленте,
от u8 до u15 -- диски и барабаны, u16 -- устройство
чтения перфокарт, u17 -- устройство записи перфокарт, u18
-- строчный принтер, u19 -- текстовый терминал, и u20 --
перфоленточное устройство. Наша реализация отображает эти устройства
в дисковые файлы, кроме u19, представляющего собой стандартный
вывод.
Как замечено выше, компьютер MIX взаимодействует с внешним миров с помощью набора устройств ввода/вывода, которые могут быть к нему "подключены". Компьютер обменивается информацией, используя блоки слов, длина которых зависит от устройства (see section 6.3 Блочные устройства MIX). Эти слова интерпретируются устройством либо как двоичная информация (для устройств 0-16), либо как представление печатаемых литер (устройства 17-20). В последнем случае каждый байт MIX отображается в литеру в соответствии со следующей таблицей:
| 00 | 01 | A | 02 | B | 03 | C | |
| 04 | D | 05 | E | 06 | F | 07 | G |
| 08 | H | 09 | I | 10 | d | 11 | J |
| 12 | K | 13 | L | 14 | M | 15 | N |
| 16 | O | 17 | P | 18 | Q | 19 | R |
| 20 | s | 21 | p | 22 | S | 23 | T |
| 24 | U | 25 | V | 26 | W | 27 | X |
| 28 | Y | 29 | Z | 30 | 0 | 31 | 1 |
| 32 | 2 | 33 | 3 | 34 | 4 | 35 | 5 |
| 36 | 6 | 37 | 7 | 38 | 8 | 39 | 9 |
| 40 | . | 41 | , | 42 | ( | 43 | ) |
| 44 | + | 45 | - | 46 | * | 47 | / |
| 48 | = | 49 | $ | 50 | < | 51 | > |
| 52 | @ | 53 | ; | 54 | : | 55 | ' |
Наконец, компьютер MIX имеет виртуальный центральный процессор, управляющий вышеперечисленными компонентами, который может выполнять богатый набор инструкций (составляющих его машинный язык, похожий на используемые в реальных центральных процессорах), включая арифметические и логические операции, инструкции помещения значения в память, сравнения и перехода. Являясь типичным компьютером фон Неймана, ЦП MIX последовательно (если только не встречается инструкция перехода) извлекает из памяти двоичные инструкции и сохраняет адрес следующей выполняемой инструкции во внутреннем регистре, называемом счётчиком положения (в других архитектурах также известен как программный счётчик).
Следующий раздел, See section 2.1.2 Набор инструкций MIX, даёт полное описание доступных двоичных инструкций MIX.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В следующих подразделах полностью описан набор инструкций компьютера MIX. Мы начнём с описания структуры двоичной инструкции и используемой для ссылки на её поля нотации. Остальные подразделы посвящены описанию собственно инструкций, которые может использовать программист MIX.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Инструкции MIX кодируются словами со следующей структурой полей:
| Поле | fspec | Описание |
| ADDRESS | (0:2) | Первые два байта и знак являются полем адреса. Вместе с полем INDEX они обозначают используемый инструкцией адрес памяти. |
| INDEX | (3:3) | Третий байт -- индекс, обычно используемый для модификации адреса(4). |
| MOD | (4:4) | Четвёртый байт используется либо как модификатор кода операции, либо как спецификация поля. |
| OPCODE | (5:5) | Последний (младший) байт слова определяет код операции. |
или, графически,
------------------------------------------------ | 0 | 1 | 2 | 3 | 4 | 5 | ------------------------------------------------ | ADDRESS | INDEX | MOD | OPCODE | ------------------------------------------------ |
Для каждой инструкции `M' обозначает адрес памяти, получаемый после модификации поля ADDRESS байтом INDEX, а `V' -- содержимое описываемого байтом MOD поля ячейки памяти с адресом `M'. Например, предположим, что содержимое регистров и ячеек памяти MIX таково:
[rI2] = + 00 63 [31] = - 10 11 00 11 22 |
ADDRESS = - 00 32 = -32 INDEX = 02 = 2 MOD = 11 = (1:3) OPCODE = 10 M = ADDRESS + [rI2] = -32 + 63 = 31 V = [M](MOD) = (- 10 11 00 11 22)(1:3) = + 00 00 10 11 00 |
Обратите внимание, при вычислении `V', используя слово и спецификацию поля, мы применяем к выбранным `MOD' байтам левое заполнение, чтобы получить в качестве результата целое слово.
В следующих подразделах мы присвои каждой инструкции MIX мнемонику или символическое имя. Например, мнемоникой инструкции с `OPCODE' 10 будет `LD2'. Таким образом, вышеприведённую инструкцию можно переписать:
LD2 -32,2(1:3) |
MNEMONIC ADDRESS,INDEX(MOD) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Для загрузки содержимого памяти в регистр могут использоваться следующие инструкции:
LDA
rA <- V.
LDX
rX <- V.
LDi
rIi <- V.
LDAN
rA <- -V.
LDXN
rX <- -V.
LDiN
rIi <- -V.
Во всех вышеперечисленных инструкиях поле `MOD' выбирает байты из ячейки памяти с адресом `M', загружаемые в нужный регистр (указанный `OPCODE'). Например, слово `+ 00 13 01 27 11' представляет собой инструкцию:
LD3 13,1(3:3) ^ ^ ^ ^ | | | | | | | --- MOD = 27 = 3*8 + 3 | | --- INDEX = 1 | --- ADDRESS = 00 13 --- OPCODE = 11 |
[rI1] = - 00 01 [rI3] = + 24 12 [12] = - 01 02 03 04 05 |
V = [M](3:3) = (- 01 02 03 04 05)(3:3) = + 00 00 00 00 03 |
[rI1] = - 00 01 [rI3] = + 00 03 [12] = - 01 02 03 04 05 |
Чтобы ещё проиллюстрировать команды загрузки, приведём таблицу, показывающую содержимое `rX' после различных инструкций `LDX':
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Следующие инструкции обратны операциям загрузки -- они используются для запоминания поля регистра в памяти. Здесь MOD обозначает поле ячейки памяти, которое должно быть перезаписано байтами из регистра. Берутся самые правые байты регистра.
STA
V <- rA.
STX
V <- rX.
STi
V <- rIi.
STJ
V <- rJ.
STZ
V <- 0.
Для примера, рассмотрим инструкцию `STA 1200(2:3)'. Она заставит MIX взять байты 4 и 5 регистра A и скопировать и в байты 2 и 3 ячейки памяти 1200 (помните, что в этих инструкциях MOD задаёт поле адреса памяти). Остальные байты ячейки памяти сохраняют своё значение. Так, если до выполнения инструкции:
[1200] = - 20 21 22 23 24 [rA] = + 01 02 03 04 05 |
[1200] = - 20 04 05 23 24 [rA] = + 01 02 03 04 05 |
Ещё один пример: `ST2 1000(0)' установит знак `[1000]' равным знаку `[rI2]'.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Следующие инструкции осуществляют арифметические операции над регистрами rA и rX и содержимым памяти.
ADD
rA <- rA +V.
SUB
rA <- rA - V.
MUL
rAX <- rA x V.
DIV
rA <- rAX / V, rX <- остаток.
Во всех вышеперечисленных инструкциях одним из операндов бинарной арифметической операции является `[rA]', другим -- `V' (заданное поле ячейки памяти с адресом `M'), заполненное нулевыми байтами слева до полного слова. В операциях умножения и деления регистр `X' играет роль правого расширения регистра `A', так что мы можем работать с 10-байтовыми числами, старшие байты которых располагаются в `rA' (знаком 10-байтового числа является знак `rA', знак `rX' игнорируется).
Сложение и вычитание слов MIX может приводить к переполнению, поскольку результат сохраняется в регистре, содержащем только 5 байтов (и знак). Если это происходит, в `rA' помещается результат операции по модулю 1 073 741 823 (максимальное значение, хранимое в слове MIX) и устанавливается триггер переполнения.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В этих инструкциях `M' (адрес после модификации) используется как число, а не как адрес ячейки памяти. Соответственно, `M' может иметь любое допустимое для слова значение (т.е. не ограничено диапазонов адресов памяти 0-3999).
ENTA
rA <- M.
ENTX
rX <- M.
ENTi
rIi <- M.
ENNA
rA <- -M.
ENNX
rX <- -M.
ENNi
rIi <- -M.
INCA
rA <- rA + M.
INCX
rX <- rX + M.
INCi
rIi <- rIi + M.
DECA
rA <- rA - M.
DECX
rX <- rX - M.
DECi
rIi <- rIi - M.
В вышеперечисленных инструкциях поле `ADDRESS' (модифицированное) играет роль непосредственного операнда, и позволяет напрямую устанавливать содержимое регистров MIX без перенаправления к ячейкам памяти (в реальных процессорах это означает, что они выполняются быстрее, чем обсуждавшиеся ранее инструкции, операнды которых берутся из памяти). Так, если вы хотите поместить в `rA' значение -2000 (- 00 00 00 31 16), вы можете использовать двоичную инструкцию + 31 16 00 03 48, или, символически,
ENNA 2000 |
Имейте в виду, что в командах пересылки адреса поле `MOD' -- не спецификатор поля, а служит для определения (вместе с `OPCODE') конкретной выполняемой операции.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
До сих пор мы изучали, как перемещать значения между регистрами и ячейками памяти MIX, а также как осуществлять арифметические операции над этими значениями. Но для написания нетривиальных программ нужны и другие возможности. Одна из наиболее общих -- возможность сравнивать два значения, которая, вместе с переходами, позволит обрабатывать условные операторы.
Следующие инструкции сравнивают значение регистра с `V' и соответствующим образом устанавливают индикатор CM (т.е., `E', `G' или `L', "равно", "больше" или "меньше" соответственно).
CMPA
CMPX
CMPi
Как объяснено выше, эти инструкции изменяют значение индикатора сравнения MIX. Вы можете спросить, как можно использовать это значение. Для этого служат команды перехода, описанные в следующем подразделе.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Компьютер MIX содержит внутренний регистр, называемый счётчиком
положения, сохраняющий адрес следующей инструкции, которая должна быть
получена из памяти и обработан виртуальным процессором. Вы не можете
напрямую изменять содержимое этого внутреннего регистра инструкцией
загрузки: после получения текущей инструкции он автоматически
увеличивается на 1 самим MIX. Тем не менее, существует набор инструкций
(называемых инструкциями перехода), которые могут изменять содержимое
счётчика положения при выполнении некоторого условия. При этом
значение адреса инструкции, которая выполнялась бы следующей, если бы
не было перехода, помещается в `rJ' (кроме JSJ), а значение
счётчика положения устанавливается равным `M' (таким образом, следующая
инструкция берётся по этому новому адресу). Позднее вы можете вернуться
к отправной точке перехода, читая адрес, сохранённый в `rJ'.
Компьютер MIX имеет следующие инструкции перехода:
Эти инструкции выполняют обязательный переход по указанному адресу. Используйте `JSJ', если адрес возврата вам не нужен.
JMP
JSJ
Эти инструкции для принятия решения о переходе проверяют триггер переполнения.
JOV
JNOV
В следующих инструкциях переход обусловлен содержимым флага сравнения:
JL
[CM] = L. OPCODE = 39, MOD = 4.
JE
[CM] = E. OPCODE = 39, MOD = 5.
JG
[CM] = G. OPCODE = 39, MOD = 6.
JGE
[CM] не равно L. OPCODE = 39, MOD = 7.
JNE
[CM] не равно E. OPCODE = 39, MOD = 8.
JLE
[CM] не равно G. OPCODE = 39, MOD = 9.
Вы можете также осуществлять переход в зависимости от значений регистров MIX, используя следующие инструкции:
JAN
JAZ
JAP
JANN
JANZ
JANP
JXN
JXZ
JXP
JXNN
JXNZ
JXNP
JiN
JiZ
JiP
JiNN
JiNZ
JiNP
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Как объясняется в предыдущих разделах (see section 2.1.1 Архитектура MIX), компьютер MIX может взаимодействовать с большим количеством блочных устройств. Для этого в вашем распоряжении имеются следующие инструкции:
IN
OUT
IOC
JRED
JBUS
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Следующие инструкции осуществляют преобразования между числовыми значениями и их литерными представлениями.
NUM
CHAR
[rA] = + 30 30 31 32 33 [rX] = + 31 35 39 30 34 |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Следующие инструкции осуществляют побайтовый сдвиг содержимого `rA' и `rX'.
SLA
SRA
SLAX
SRAX
SLC
SRC
| SLA 2 | [rA] = - 03 04 05 00 00 |
| SRA 1 | [rA] = - 00 01 02 03 04 |
| SLC 3 | [rA] = - 04 05 01 02 03 |
| SRC 24 | [rA] = - 05 01 02 03 04 |
[rA] = + 04 05 06 07 08 [rX] = - 09 10 00 00 00 |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Наконец, приведём список трёх остальных инструкций MIX, не описанных в предыдущих подразделах:
MOVE
NOP
HLT
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
При написании программ на MIXAL (или любых других программ) нас часто интересует время их выполнения. Приблизительно, нас интересует ответ на вопрос: как долго будет выполняться программа? Конечно, это время выполнения является функцией от объёма входных данных, и ответ на наш вопрос обычно даётся в виде асимптотического поведения функции от объёма входных данных. В любом случае, для вычисления асимпотического приближения нам нужна мера времени выполнения одной инструкции на нашем (виртуальном) процессоре. Поэтому с каждой инструкцией MIX связано время выполнения, заданное в относительных единицах (в реальных компьютерах значение этой единицы зависит от аппаратной конфигурации). Когда наша виртуальная машина MIX выполняет программы, она может (по желанию) выводить значение времени выполнения на основе времени выполнения каждой отдельной инструкции.
В следующей таблице приведены значения времени выполнения (в вышеупомянутых относительных единицах) инструкций MIX.
NOP | 1 | ADD | 2 | SUB |
2 | MUL | 10 |
DIV | 12 | NUM | 10 | CHAR |
10 | HLT | 10 |
SLx | 2 | SRx | 2 | LDx |
2 | STx | 2 |
JBUS | 1 | IOC | 1 | IN |
1 | OUT | 1 |
JRED | 1 | Jx | 1 | INCx |
1 | DECx | 1 |
ENTx | 1 | ENNx | 1 | CMPx |
1 | MOVE | 1+2F |
В таблице 'F' обозначает число перемещаемых блоков (заданное полем
FSPEC инструкции), SLx и SRx -- сокращения для операций
побайтового сдвига, LDx обозначает все операции загрузки,
STx -- все операции запоминания, Jx обозначает
все операции перехода, и т.д. для остальный сокращений.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В предыдущих разделах мы перечислили все существующие двоичные инструкции MIX. Как мы показали, каждая инструкция представляется словом, которое достаётся из памяти и обрабатывается виртуальным центральным процессором MIX. Как и в случае реальных компьютеров, MIX может декодировать инструкции в двоичном формате (так называемый машинный язык), но программист-человек, пишущий программу на машинном языке, вряд ли весело проведёт время. К счастью, MIX можно программировать на языке ассемблера, MIXAL, предоставляющем способ написания понимаемых воображаемым компьютером MIX двоичных инструкций в символьном виде. Если вы ранее использовали языки ассемблера, вы найдёте в MIXAL очень много знакомого. Исходные файлы MIXAL транслируются в машинный язык ассемблером MIX, создающим двоичный файл (реальная программа MIX), который может быть непосредственно загружен в память MIX и последовательно выполнен.
В этом разделе мы опишем MIXAL, язык ассемблера MIX. Реализации ассемблера MIX и эмулятора компьютера MIX, входящие в состав MDK, описаны позднее (see section 3. Начало работы).
2.2.1 Базовая структура программы Написание базовых программ на MIXAL. 2.2.2 Директивы MIXAL Директивы ассемблера. 2.2.3 Выражения 2.2.4 W-выражения Вычисление w-выражений. 2.2.5 Локальные символы 2.2.6 Литеральные константы
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Ассемблер MIX читает файлы MIXAL построчно, создавая, при необходимости, двоичную инструкцию, связанную с определённым адресом в памяти. Чтобы следить за текущим адресом, ассемблер поддерживает внутренний счётчик положения, увеличиваемый при каждой компиляции инструкции. Кроме инструкция MIX в файл MIXAL можно включать директивы ассемблера (или псевдоинструкции), предназначенные для самого ассемблера (например, указывающие, где начинается и заканчивается программа, или переопределяющие счётчик положения, см. ниже).
Инструкции MIX и директивы ассемблера(7) записываются на MIXAL (одна на строку исходного файла) в соответствии со следующим шаблоном:
[LABEL] MNEMONIC [OPERAND] [COMMENT] |
где `ОПЕРАНД' имеет вид:
[ADDRESS][,INDEX][(MOD)] |
Элементы, заключённые в круглые скобки могут отсутствовать.
LABEL
MNEMONIC
LDA,
STA, see section 2.1.2 Набор инструкций MIX) или псевдоинструкцию
ассемблера (например, ORIG, EQU),
ADDRESS
INDEX
ADDRESS,
MOD
OPCODE,
COMMENT
Обратите внимание, что между полями ADDRESS, INDEX и
MOD, если они присутствуют, пробелы недопустимы.
Для разделения метки, кода операции и операнда в инструкции используются
пробелы(8).
Мы уже перечислили мнемоники, сопоставленные каждой инструкции MIX. Приведём пример инструкций MIXAL, представляющих инструкции MIX:
HERE LDA 2000 HERE представляет текущий счётчик положения
LDX HERE,2(1:3) это комментарий
JMP 1234
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Инструкция MIXAL может быть либо одной из машинных инструкций MIX (see section 2.1.2 Набор инструкций MIX), либо одной из следующих псевдоинструкций ассемблера:
ORIG
EQU
SYM EQU 2*200/3.
CON
ALF
END
Операндом ORIG, EQU, CON и END может
быть любое выражение, задающее слово MIX-константу, т.е. либо простое
выражение MIXAL (состоящее из чисел, символов и бинарных операций,
see section 2.2.3 Выражения), либо w-выражение (see section 2.2.4 W-выражения).
Любая программа на MIXAL должна содержать директиву END с двоякой
целью: во-первых, она обозначает точку прекращения работы ассемблера,
и во-вторых, её (обязательный) операнд указывает начальный адрес
скомпилированной программы (адрес, по которому виртуальная машина MIX
должна начать разбор инструкций после загрузки программы). Также
является обычной практикой (хотя и не обязательно) включать в программу
по крайней мере одну директиву ORIG, чтобы обозначить начальное
значение счётчика положения ассемблера (помните, что он содержит адрес,
связанные с каждой скомпилированной инструкцией MIX). Таким образом,
минимальной программой на MIXAL будет:
ORIG 2000 установить начальный адрес компиляции
NOP эта инструкция будет загружена по адресу 2000
HLT а эта по адресу 2001
END 2000 конец программы, начало по адресу 2000
эта строка не анализируется ассемблером
|
NOP (+ 00 00 00 00 00)
и HLT (+ 00 00 02 05)), которые будут загружены по адресам
2000 и 2001. Выполнение программы начнётся с адреса 2000. Каждая
программа на MIXAL должна также содержать инструкцию HLT,
которая означает конец выполнения программы (но не компиляции программы).
Директива EQU позволяет определять символические имена заданных
значений. Например, мы можем переписать вышеприведённую программу
следующим образом:
START EQU 2000
ORIG START
NOP
HLT
END START
|
LABEL инструкции MIXAL. В этом случае перед компиляцией
строки ассемблер присвоит символу значение счётчика положения. Поэтому
третий способ записи нашей тривиальной программы:
ORIG 2000
START NOP
HLT
END START
|
Директива CON позволяет непосредственно задавать содержимое,
находящееся в памяти по адресу, указанному счётчиком положения. Например,
если ассемблер встретит следующий участок кода:
ORIG 1150
CON -1823473
|
Наконец, директива ALF позволяет задавать содержимое памяти
как набор пяти литер (в кавычках), которые транслируются ассемблером
в соответствующие значения байтов, создавая, таким образом, двоичное
слово, размещаемое в соответствующей ячейке памяти. Эта директива
полезна, если вам нужно поместить по адресу памяти сообщения для печати,
как в следующем примере:
OUT MSG MSG здесь ещё не определено (ссылка вперёд)
MSG ALF "THIS " MSG определяется здесь
ALF "IS A "
ALF "MESSA"
ALF "GE. "
|
MSG) до его
реального определения. Ассемблер MIXAL может обрабатывать ссылки вперёд
с некоторыми ограничениями, описанными в следующем разделе
(see section 2.2.3 Выражения).
Любая строка, начинающаяся со звёздочки, считается комментарием и игнорируется ассемблером.
* Это комментарий: эта строка игнорируется.
* Это ошибка: * должна быть в первой колонке.
|
Как показано в предыдущем разделе, комментарии могут также быть расположены
после поля OPERAND инструкции, отделённые от него пробелами:
LABEL LDA 100 Это также комментарий |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
ADDRESS, INDEX и MOD инструкции MIXAL могут
быть выражениями, состоящими из чисел, идентификаторов и знаков бинарных
операций (+ - * / // :). + и - могут также использоваться
как знаки унарных операций. Операторы выполняются слева направо, других
правил приоритета операторов нет, и использовать скобки для группировки
нельзя. Отдельная звёздочка обозначает текущее положение в памяти. Так,
например:
4+2** |
обозначает 6 (4+2), умноженное на текущее положение в памяти. Пробелы внути выражений не допускаются.
Специальная бинарная операция : имеет то же значения, что и в
спецификациях полей, т.е.
A:B = 8*A + B |
A//B обозначает деление 10-байтового числа
A 00 00 00 00 00 (A, дополненное справа пятью нулевыми байтами,
или, что то же самое, умноженное на 64 в пятой степени), разделённое
на B. Примеры выражений:
18-8*3 = 30 14/3 = 4 1+3:11 = 4:11 = 43 1//64 = (01 00 00 00 00 00)/(00 00 00 01 00) = (01 00 00 00 00) |
Все символы, встречающиеся в выражениях, должны бы предварительно определены.
Ссылки вперёд допускаются только если встречаются отдельно (или с унарной
операцией) в части ADDRESS инструкции MIXAL, например:
* OK: отдельная ссылка вперёд
STA -S1(1:5)
* ERROR: ссылка вперёд в выражении
LDX 2-S1
S1 LD1 2000
|
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Помимо описанных выше (see section 2.2.3 Выражения) выражений, ассемблер MIXAL
может обрабатывать в качестве операндов директив ORIG, EQU,
CON и END (see section 2.2.2 Директивы MIXAL) так называемые
w-выражения. Общий вид w-выражения таков:
WEXP = EXP[(EXP)][,WEXP] |
EXP обозначает выражение, а квадратные скобки отмечают
необязательные элементы. Таким образом, w-выражение состоит из выражения,
за которым следует необязательное выражение в круглых скобках, а затем
любое число аналогичных конструкций, разделённых запятыми. Примеры
w-выражений:
2000 235(3) S1+3(S2),3000 S1,S2(3:5),23 |
W-выражения вычисляются слева направо следующим образом:
Ещё один пример -- в w-выражении
1(1:2),66(4:5) |
1(1:1),2(2:2),3(3:3),4(4:4) = 01 02 03 04 00 |
Как указано выше, w-выражения могут встречаться только в операндах
директив MIXAL, принимающих константное значений (ORIG, EQU,
CON и END). Ссылки вперёд в w-выражениях не
допускаются (т.е., все символы, встречающиеся в w-выражении должны
быть определены до их использования).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Помимо определённых пользователем символов, программисты на MIXAL
могут использовать так называемые локальные символы, т.е.
символы вида [1-9][HBF]. Локальный символ nB ссылается
на адрес, где в последний раз в качестве метки служило nH,
а nF -- на следующее появление nH. В отличие от
определённых пользователем символов, nH может встречаться
в части LABEL различных инструкций MIXAL сколько угодно раз.
Следующий код даёт пример использования локальных символов:
* строка 1
1H LDA 100
* строка 2: 1B ссылается на адрес строки 1, 3F ссылается на адрес строки 4
STA 3F,2(1B//2)
* строка 3: переопределение 1H
1H STZ
* строка 4: 1B ссылается на адрес строки 3
3H JMP 1B
|
Имейте в виду, что локальный символ B никогда не ссылается на
определение его собственной строки. Так, в следующей программе:
ORIG 1999 ST NOP 3H EQU 69 3H ENTA 3B локальный символ 3B ссылается на 3H в предыдущей строке HLT END ST |
ORIG существует
особый трюк. Рассмотрим(9):
ORIG 1999 ST NOP 3H CON 10 ENT1 * LDA 3B ** rI1 = 2001, rA = 10. До сих пор всё нормально! 3H ORIG 3B+1000 ** в этой точке 3H равно 2003 ** а счётчик положений равен 3000. ENT2 * LDX 3B ** rI2 содержит 3000, rX содержит 2003. HLT END ST |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
MIXAL допускает введение литеральных констант, которые автоматически
помещаются ассемблером в память по адресам после конца программы.
Литеральные константы обозначаются =wexp=, где wexp --
w-выражение (see section 2.2.4 W-выражения). Например, код:
L EQU 5
LDA =20-L=
|
вынуждает ассемблер добавить после конца программы инструкцию,
содержащую 15 (`20-L') и ассемблировать вышеприведённый код
как инструкцию LDA a, где a обозначает адрес,
по которому помещается значение 15. Другими словами, скомпилированный
код эквивалентен следующему:
L EQU 5
LDA a
...
a CON 20-L
END start
|
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |