Node:Написание исходного файла, Next:Компиляция, Previous:Начало работы, Up:Начало работы
Программы на MIXAL могут быть написаны в виде ASCII-файлов в любом
текстовом редакторе. Приведём обязательную программу hello world,
написанную на языке ассемблера MIXAL.
* (1)
* hello.mixal: сказать 'hello world' на MIXAL (2)
* (3)
* label ins operand comment (4)
TERM EQU 19 номер устройства консоли в MIX (5)
ORIG 1000 начальный адрес (6)
START OUT MSG(TERM) вывести данные с адреса MSG (7)
HLT прекратить работу (8)
MSG ALF "MIXAL" (9)
ALF " HELL" (10)
ALF "O WOR" (11)
ALF "LD " (12)
END START конец программы (13)
При использовании утилит MDK исходным файлам MIXAL следует давать
расширение .mixal. Как вы можете видеть в этом примере,
каждая строка в файле MIXAL может быть разделена на четыре поля,
разделённые любым количеством пробельных символов (пробелы и знаки
табуляции). В определении MIXAL Кнута каждое поле должно начинаться
в фиксированной колонке, но ассемблер MDK ослабляет это требование
и позволяет форматировать файл по вашему усмотрению. Ограничения связаны
только со строками комментариев (такими, как 1-4), которые должны
начинаться со звёздочки (*), помещённой в первой колонке, и с полями
меток (см. ниже), которые, если они присутствуют, также должны начинаться
в первой колонке. Четыре поля, присутствующие в каждой строке, не
являющейся комментарием, это:
START и MSG в строках 7 и 9), либо определяет
символ (TERM) (если она присутствует, метка обязана начинаться
в первой колонке строки, ибо первый пробельный символ в строке
отмечает начало второго поля).
OUT и HLT в строках 7 и 9), либо псевдоинструкцию
ассемблера (например, псевдоинструкция ORIG в строке
61).
Строки 9-12 в файле hello.mixal показываеют также второе (и
последнее) различие между определениями MIXAL Кнута и нашими: операнд
псевдоинструкции ALf (слово из пяти литер) должно быть заключено
в двойные кавычки2.
Если вы знакомы с MIXAL, работа этого примера программы должна быть понятна. См. полное определение MIXAL в томе 1 "Искусства программирования", учебник - Учебник по MIX и MIXAL.
Если директива ORIG не используется, программа
будет загружена виртуальной машиной по адресу 0. ORIG
позволяет расположить исполняемый код по вашему усмотрению.
В определении Кнута операнд всегда начинается
с фиксированной колонки, и поэтому использование кавычек необязательно.
Поскольку mixasm не содержит этого ограничения, для устранения
неоднозначности разбора этого операнда в случаях, когда он содержит
пробелы, используются кавычки. Имейте в виду, что двойные кавычки не
входят в набор литер MIX, и поэтому экранировать литеры внутри
операндов ALF не нужно.
Node:Определение новых функций, Next:Функции-ловушки, Previous:Дополнительные функции, Up:Использование mixguile
Scheme - мощный язык, и вы можете использовать его внутри mixguile,
чтобы легко расширять возможности интерпретатора MIX. Например, вы легко
можете определить функцию, загружающую файл, выводяющую его имя,
выполняющую его и, наконец, показывающую содержимое регистров, всё в один
приём:
guile> (define my-load-and-run <RET>
(lambda (file) <RET>
(mix-load file) <RET>
(display "File loaded: ") <RET>
(mix-pprog) <RET>
(mix-run) <RET>
(mix-preg))) <RET>
guile>
и использовать её для запуска ваших программ:
guile> (my-load-and-run "hello") Program loaded. Start address: 3000 File loaded: hello.mix Running ... MIXAL HELLO WORLD ... done Elapsed time: 11 /Total program time: 11 (Total uptime: 33) rA: + 00 00 00 00 00 (0000000000) rX: + 00 00 00 00 00 (0000000000) rJ: + 00 00 (0000) rI1: + 00 00 (0000) rI2: + 00 00 (0000) rI3: + 00 00 (0000) rI4: + 00 00 (0000) rI5: + 00 00 (0000) rI6: + 00 00 (0000) guile>
Или, быть может, вы хотите иметь функцию, перед выполнением программы
устанавливающую точку останова на указанной строке:
guile> (define my-load-and-run-with-bp
(lambda (file line)
(mix-load file)
(mix-sbp line)
(mix-run)))
guile> (my-load-and-run-with-bp "samples/primes" 10)
Program loaded. Start address: 3000
Breakpoint set at line 10
Running ...
... stopped: breakpoint at line 10 (address 3001)
Elapsed time: 1 /Total program time: 1 (Total uptime: 45)
guile>
Третьим примером рассмотрим функцию, загружающую программу, выполняющую
её и выводящую содержимое памяти между начальным и конечным адресами
программы:
guile> (define my-run
(lambda (file)
(mix-load file)
(let ((start (mix-loc)))
(mix-run)
(mix-pmem start (mix-loc)))))
guile> (my-run "hello")
Program loaded. Start address: 3000
Running ...
MIXAL HELLO WORLD
... done
Elapsed time: 11 /Total program time: 11 (Total uptime: 11)
3000: + 46 58 00 19 37 (0786957541)
3001: + 00 00 00 02 05 (0000000133)
3002: + 14 09 27 01 13 (0237350989)
guile>
Как вы видите, возможности практически не ограничены. Конечно, вводить
определение функций при каждом запуске mixguile не нужно. Вы можете
записать их в файл и загрузить функцией Scheme load. Например,
вы можете создать файл, скажем, functions.scm с вашими определениями
(или любыми выражениями Scheme) и загрузить его в приглашении mixguile:
guile> (load "functions.scm")
Кроме того, вы можете указать mixguile загружать его каждый раз.
При запуске mixguile, она проверяет файл mixguile.scm в
каталоге конфигурации MDK (~/.mdk) и, если он существует,
загружает его перед тем, как войти в REPL. Поэтому вы можете скопировать
ваши определения в этот файла или загрузить functions.scm из
mixguile.scm.
Node:Дополнительные функции ВМ, Previous:Ловушки, Up:Описание функций Scheme
При написании нетривиальных расширений Scheme с использованием библиотеки
MIX/Scheme, вам, вероятно, будет нужно определять содержимое компонентов
виртуальной машины (регистры, ячейки памяти и т.д.). Например, вам может
понадобиться сохранить содержимое регистра A в переменной.
Функции Scheme, описанные до сих пор, не помогут - вы можете вывести
содержимое A функцией (mix-preg 'A), но не можете присвоить
значение A переменной. Для решения этой проблемы библиотека
MIX/Scheme предоставляет следующие дополнительные функции:
| mixvm-status | Function |
| mix-vm-status | Function |
Возвращает текущий статус виртуальной машины в виде числа
(mixvm-status) или символа (mix-vm-status). Возможные
возвращаемые значения:
|
| mix-vm-error? | Function |
| mix-vm-break? | Function |
| mix-vm-cond-break? | Function |
| mix-vm-halted? | Function |
| mix-vm-running? | Function |
| mix-vm-loaded? | Function |
| mix-vm-empty? | Function |
Предикаты, проверяющие равенство текущего статуса виртуальной
машины MIX_ERROR, MIX_BREAK и т.д.
|
| mix-reg register | Function |
| mix-set-reg! register value | Function |
mix-reg возвращает содержимое указанного регистра в виде
числа. mix-set-reg приравнивает значение указанного регистра
заданному. Регистр может быть задан либо в виде строки ("A",
"X" и т.д.), либо в виде символа ('A, 'X и т.д.).
Например:
guile> (mix-reg 'A) 2341 guile> (mix-set-reg! "A" 2000) ok guile> (define reg-a (mix-reg 'A)) guile> (display reg-a) 2000 guile> |
| mix-cell cell_no | Function |
| mix-set-cell! cell_no value | Function |
| Возвращает и устанавливает содержимое ячейки памяти номер cell_no соответственно. И cell_no, и value - числа Scheme. |
| mix-loc | Function |
| Возвращает значение счётчика положения (т.е. адрес следующей выполняемой инструкции). |
| mix-over | Function |
| mix-set-over! #t|#f | Function |
mix-over возвращает #t, если триггер переполнения
установлен, и #f в противном случае. Значение триггера
переполнения может быть изменено функцией mix-set-over!.
|
| mix-cmp | Function |
| mix-set-cmp! 'L|'E|'G | Function |
Возвращает и устанавливает флаг сравнения соответственно. Возможные
значения - символы Scheme L (меньше), E (равно) и
G (больше).
|
| mix-up-time | Function |
| Возвращает текущее время работы виртуальной машины. |
| mix-lap-time | Function |
Возвращает текущее прошедшее время виртуальной машины, т.е. время,
прошедшее после последней команды run или next.
|
| mix-prog-time | Function |
| Возвращает общее время выполнения загруженной в данный момент программы. |
| mix-prog-name | Function |
| Возвращает строку, содержащую базовое имя (без пути) загруженной в данный момент программы MIX. |
| mix-prog-path | Function |
| Возвращает строку, содержащую полный путь к загруженной в данный момент программе MIX. |
| mix-src-path | Function |
| Возвращает строку, содержащую полный путь к исходному файлу загруженной в данный момент программы MIX. |
| mix-src-line [lineno] | Function |
| mix-src-line-no | Function |
mix-src-line-no во время выполнения программы возвращает номер
текущей строки исходного кода. mix-src-line возвращает строку,
содержащую строку исходного файла номер lineno, а при вызове
без аргументов возвращает (mix-src-line (mix-src-line-no)).
|
| mix-ddir | Function |
| Возвращает строку, содержащую полный путь к текущему каталогу устройств. |