Model machine emulator
Модельная машина - это чистая архитектурная концепция, позволяющая понять логику функционирования центральных процессоров. По своей структуре она близка к компьютерам первого поколения. Подробнее читайте по ссылкам внизу.
Установка пакета происходит командой:
# python3 -m pip install --upgrade modelmachine
После этого вам становится доступна консольная команда modelmachine.
Посмотрите примеры в папке samples, по их образу можно начинать писать программы для модельных машин. Запуск программы производится командой:
$ modelmachine run samples/mm-3_sample.mmach
Также доступна пошаговая отладка командой:
$ modelmachine debug samples/mm-3_sample.mmach
.cpu mm-3
.input 0x100 a
.input 0x101 b
.output 0x103 x
.code
; x = ((a * -21) % 50 - b) ** 2 == 178929
03 0100 0005 0103 ; x := a * -21
04 0103 0006 0102 ; [0102] := x / 50, x := x % 50
02 0103 0101 0103 ; x := x - b
03 0103 0103 0103 ; x := x * x
99 0000 0000 0000 ; halt
; ---------------------
FFFFFFFFFFFFEB ; -21
00000000000032 ; 50
.enter -123 456
- Все, что идет после символа
;- комментарий; пустые строки игнорируются. - Программа должна начинаться с директивы
.cpuи указания архитектуры. Список поддерживаемых архитектур смотри ниже. - Текст программы обязан содержать директиву
.codeпосле которой идет секция кода, содержащая набор 16-ричных чисел, записываемых в память модельной машины. Пропускать часть машинного слова нельзя. Рекомендуется писать по одному машинному слову в строке, по желанию разбивая разряды на части пробелами.- По умолчанию директива
.codeзагружает данные начиная с адреса0. - Модельная машина начинает исполнение программы с адреса
0. - Секций
.codeможет быть несколько. В этом случае после директивы.codeнужно указать адрес по которому нужно загружать данные. Например,.code 0x100. Участки памяти, в которые загружаются данные различными директивами, обязаны не пересекаться
- По умолчанию директива
- Директива
.input ADDRESS [QUESTION]читает данные из потока ввода по адресуADDRESSдо запуска модельной машины.ADDRESSможет использовать десятичный15или шеснадцатеричный0xffформат.- Вводить также можно десятичные и шеснадцатеричные числа со знаком.
- При вводе из консоли, пользователь увидит вопрос
QUESTION; при вводе из файлаQUESTIONбудет игнорироваться. - В директиве можно указывать несколько адресов, резделённых запятой, например,
.input 0x200, 0x204, 0x208 Enter three numbers.
- Необязательная директива
.enter NUMBERS...вводит числа для директив.input.NUMBERS— это строка, в которой числа раздлелены пробелами.- Требуется вводить ровно столько чисел, сколько адресов было указано
в директивах
.input. - Если запуск программы производится с ключом
--enter, то директива.enterигнорируется и данные для.inputпоступают из консоли или файла. - Это позволяет для отладки записать данные вместе с программой, а потом запускать ее из консоли с разными параметрами.
- Директива
.output ADDRESS [MESSAGE]печатает данные в поток вывода после остановки машины.- Данные печатаются в виде десятичных чисел со знаком.
- Если произошла ошибочная ситуация (например, деление на 0), то вывод производится не будет.
- В директиве можно указывать несколько адресов, резделённых запятой.
- Больше примеров в папке samples
- Для всех машин поддерживается язык ассемблера
| OPCODE | mm-3 | mm-2 | mm-v | mm-1 | mm-s | mm-0 | mm-r | mm-m |
|---|---|---|---|---|---|---|---|---|
| 0x00 | move | move | move | load | load | load | ||
| 0x01 | add | add | add | add | add | add | add | add |
| 0x02 | sub | sub | sub | sub | sub | sub | sub | sub |
| 0x03 | smul | smul | smul | smul | smul | smul | smul | smul |
| 0x04 | sdiv | sdiv | sdiv | sdiv | sdiv | sdiv | sdiv | sdiv |
| 0x05 | comp | comp | comp | comp | comp | comp | comp | |
| 0x13 | umul | umul | umul | umul | umul | umul | umul | umul |
| 0x14 | udiv | udiv | udiv | udiv | udiv | udiv | udiv | udiv |
| 0x10 | store | store | store | |||||
| 0x11 | addr | |||||||
| 0x20 | swap | rmove | rmove | |||||
| 0x21 | radd | radd | ||||||
| 0x22 | rsub | rsub | ||||||
| 0x23 | rsmul | rsmul | ||||||
| 0x24 | rsdiv | rsdiv | ||||||
| 0x25 | rcomp | rcomp | ||||||
| 0x33 | rumul | rumul | ||||||
| 0x34 | rudiv | rudiv | ||||||
| 0x40 | push | |||||||
| 0x5A | push | |||||||
| 0x5B | pop | pop | ||||||
| 0x5C | dup | dup | ||||||
| 0x5D | swap | swap | ||||||
| 0x80 | jump | jump | jump | jump | jump | jump | jump | jump |
| 0x81 | jeq | jeq | jeq | jeq | jeq | jeq | jeq | jeq |
| 0x82 | jneq | jneq | jneq | jneq | jneq | jneq | jneq | jneq |
| 0x83 | sjl | sjl | sjl | sjl | sjl | sjl | sjl | sjl |
| 0x84 | sjgeq | sjgeq | sjneq | sjgeq | sjgeq | sjgeq | sjgeq | sjgeq |
| 0x85 | sjleq | sjleq | sjleq | sjleq | sjleq | sjleq | sjleq | sjleq |
| 0x86 | sjg | sjg | sjg | sjg | sjg | sjg | sjg | sjg |
| 0x93 | ujl | ujl | ujl | ujl | ujl | ujl | ujl | ujl |
| 0x94 | ujgeq | ujgeq | ujgeq | ujgeq | ujgeq | ujgeq | ujgeq | ujgeq |
| 0x95 | ujleq | ujleq | ujleq | ujleq | ujleq | ujleq | ujleq | ujleq |
| 0x96 | ujg | ujg | ujg | ujg | ujg | ujg | ujg | ujg |
| 0x99 | halt | halt | halt | halt | halt | halt | halt | halt |
На самом деле операция div запускает в АЛУ схему divmod.
Ниже дана таблица команд условных переходов. Откуда берутся операнды для сравнения зависит от архитектуры модельной машины. Подробнее смотри [1].
| Мнемонический код | Условие перехода | Описание |
|---|---|---|
| jeq | == | jump if equal |
| jneq | != | jump if not equal |
| sjl | < s | signed jump if less |
| sjgeq | >= s | signed jump if greater or equal |
| sjleq | <= s | signed jump if less or equal |
| sjg | > s | signed jump if greater |
| ujl | < u | unsigned jump if less |
| ujgeq | >= u | unsigned jump if greater or equal |
| ujleq | <= u | unsigned jump if less or equal |
| ujg | > u | unsigned jump if greater |
Псевдокод
Для описание команд в тексте ниже используется псевдокод:
R_M- регистр с номеромMR- для краткости регистр с номеромRзаписывается простоRвместоR_R[A]- ячейка оперативной памяти; адрес рассчитывается по модулю размера оперативной памяти (2^16)R := [A]- загрузка данных по адресуAиз ram в регистрR[A] := R- сохранение данных из регистраRпо адресуAв ramS := R1 op R2- вычислить операциюopи сохранить результат в регистрScalc R1 op R2- вычислить операциюopи не сохранять результатS := R1 op R2 and set FLAGS,calc R1 op R2 and set FLAGS- то же самое + выставить регистрFLAGSв зависимости от результата вычисленийop(FLAGS)- условие вычисляется исходя из регистраFLAGSif C then X- действиеXпроисходит если выполнено условиеCX; Y- действияXиYпроисходят параллельно- Описание команды состоит из трех шагов, происходящих последовательно:
- load:
X - exec:
Y - write back:
Z
- load:
- Для краткости описание может быть сокращено до одного или двух шагов, если детали реализации не имеют значения.
Ошибочные ситуации
В случае ошибочной ситуации машина будет остановлена и вывод производится не будет.
Список ошибочных ситуаций:
- неверный код команды;
- деление на ноль;
- чтение/запись элемента стека за границей стека;
- чтение/запись данных за границей доступных адресов оперативной
памяти, тк ячейка оперативной памяти может быть меньше размера
операнда или команды, например при исполнении команды
move 0000 ffff.
Неописанные регистры
Все машины содержат набор общих регистров:
FLAGS- регистр флагов.PC- регистр указатель инструкции.IR- регистр для хранения инструкции.ADDR- регистр для хранения адреса для инструкции перехода.
Также машины могут содержать неадресуемые регистры:
A1, A2, R, M. В них копируются операнды из регистра IR.
Эти регистры опущены в описании модельных машин для краткости. Содержимое этих регистров можно увидеть в отладчике.
Архитектура трехадресной модельной машины.
- Размер ячейки оперативной памяти: 7 байт.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся с одной ячейкой оперативной памяти.
- Код команды помещается в одну ячейку оперативной памяти
COP А1 А2 А3. - Регистры:
S,R1,R2.
S- регистр сумматор, в него записывается результат арифметической операции.R1,R2- регистры операндов арифметических операций.
add,sub,smul,umul:- load:
R1 := [A1]; R2 := [A2] - exec:
S := R1 op R2 and set FLAGS - write back:
[A3] := S
- load:
sdiv,udiv:- load:
R1 := [A1]; R2 := [A2] - exec:
S := R1 / R2 and set FLAGS; R1 := R1 % R2 - write back:
[A3] := S; [A3 + 1] := R1
- load:
jump:PC := A3jeq,jneq,jl,jleq,jg,jgeq:- load:
R1 := [A1]; R2 := [A2] - exec:
S := R1 - R2 and set FLAGS - write back:
if op(FLAGS) then PC := A3
- load:
move:[A3] := [A1]halt:FLAGS := HALT
Архитектура двухадресной модельной машины.
- Размер ячейки оперативной памяти: 5 байт.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся с одной ячейкой оперативной памяти.
- Код команды помещается в одну ячейку оперативной памяти
COP А1 А2. - Регистры:
R1,R2.
add,sub,smul,umul:- load:
R1 := [A1]; R2 := [A2] - exec:
R1 := R1 op R2 and set FLAGS - write back:
[A1] := R1
- load:
sdiv,udiv:- load:
R1 := [A1]; R2 := [A2] - exec:
R1 := R1 / R2 and set FLAGS; R2 := R1 % R2 - write back:
[A1] := R1; [A1 + 1] := R2
- load:
jump:PC := A2cmp:- load:
R1 := [A1]; R2 := [A2] - exec:
R1 := R1 - R2 and set FLAGS
- load:
jeq,jneq,jl,jleq,jg,jgeq:if op(FLAGS) then PC := A2move:[A1] := [A2]halt:FLAGS := HALT
Архитектура модельной машины с переменным (variable) форматом команд.
- Размер ячейки оперативной памяти: 1 байт.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся со словами в 5 байтов.
- Код команды занимает разное количество ячеек в зависимости от выполняемой операции.
- Регистры:
R1,R2.
| Код команды | Мнемоник | Формат | Длина (в байтах) |
|---|---|---|---|
| 0x00 | move | move A1 A2 | 5 |
| 0x01 | add | add A1 A2 | 5 |
| 0x02 | sub | sub A1 A2 | 5 |
| 0x03 | smul | smul A1 A2 | 5 |
| 0x04 | sdiv | sdiv A1 A2 | 5 |
| 0x05 | comp | comp A1 A2 | 5 |
| 0x13 | umul | umul A1 A2 | 5 |
| 0x14 | udiv | udiv A1 A2 | 5 |
| 0x80 | jump | jump A1 | 3 |
| 0x81 | jeq | jeq A1 | 3 |
| 0x82 | jneq | jneq A1 | 3 |
| 0x83 | sjl | sjl A1 | 3 |
| 0x84 | sjgeq | sjgeq A1 | 3 |
| 0x85 | sjleq | sjleq A1 | 3 |
| 0x86 | sjg | sjg A1 | 3 |
| 0x93 | ujl | ujl A1 | 3 |
| 0x94 | ujgeq | ujgeq A1 | 3 |
| 0x95 | ujleq | ujleq A1 | 3 |
| 0x96 | ujg | ujg A1 | 3 |
| 0x99 | halt | halt | 1 |
add,sub,smul,umul- formatop A1 A2:- load:
R1 := [A1]; R2 := [A2] - exec:
R1 := R1 op R2 and set FLAGS - write back:
[A1] := R1
- load:
sdiv,udiv- formatop A1 A2:- load:
R1 := [A1]; R2 := [A2] - exec:
R1 := R1 / R2 and set FLAGS; R2 := R1 % R2 - write back:
[A1] := R1; [A1 + 1] := R2
- load:
jump A1:PC := A1cmp A1 A2:- load:
R1 := [A1]; R2 := [A2] - exec:
R1 := R1 - R2 and set FLAGS
- load:
jeq,jneq,jl,jleq,jg,jgeq- formatop A:if op(FLAGS) then PC := Amove A1 A2:[A1] := [A2]halt:FLAGS := HALT
Архитектура одноадресной модельной машины.
- Размер ячейки оперативной памяти: 3 байта.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся с одной ячейкой оперативной памяти.
- Код команды помещается в одну ячейку оперативной памяти
COP А. - Регистры:
S,R.
Регистры S и S1 хранят информацию постоянно, а не заполняются при
выполнении очередной команды, как в предыдущих машинах.
В регистр R загружается операнд для арифметических операций.
add,sub,smul,umul:- load:
R := [A] - exec:
S := S op R and set FLAGS
- load:
sdiv,udiv:- load:
R := [A] - exec:
S := S / R and set FLAGS; S1 := S % R
- load:
jump A:PC := Acmp:- load:
R := [A] - exec:
calc S - R and set FLAGS
- load:
jeq A,jneq,jl,jleq,jg,jgeq:if op(FLAGS) then PC := Aload A:S := [A]store A:[A] := Sswap:S := S1; S1 := Shalt:FLAGS := HALT
Архитектура стековой модельной машины.
- Размер ячейки оперативной памяти: 1 байт.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся со словами в 3 байта.
- Код команды занимает разное количество ячеек в зависимости от выполняемой операции.
- Регистры:
R1,R2,SP.
В регистры R1 и R2 загружаются данные из стека - ячеек оперативной
памяти по адресу [SP]. Результат вычислений записывается обратно на
вершину стека. При этом значение региста SP увеличивается или уменьшается
на размер слова 3 в зависимости от семантики команды.
Стек растет в сторону меньших адресов.
Попытка чтения данных за границами стека (например, команда POP при пустом
стеке) является ошибочной ситуацией и приведет к останову машины.
| Код команды | Мнемоник | Формат | Длина (в байтах) |
|---|---|---|---|
| 0x01 | add | add | 1 |
| 0x02 | sub | sub | 1 |
| 0x03 | smul | smul | 1 |
| 0x04 | sdiv | sdiv | 1 |
| 0x05 | comp | comp | 1 |
| 0x13 | umul | umul | 1 |
| 0x14 | udiv | udiv | 1 |
| 0x5A | push | push A | 3 |
| 0x5B | pop | pop A | 3 |
| 0x5C | dup | dup | 1 |
| 0x5D | swap | swap | 1 |
| 0x80 | jump | jump A | 3 |
| 0x81 | jeq | jeq A | 3 |
| 0x82 | jneq | jneq A | 3 |
| 0x83 | sjl | sjl A | 3 |
| 0x84 | sjgeq | sjgeq A | 3 |
| 0x85 | sjleq | sjleq A | 3 |
| 0x86 | sjg | sjg A | 3 |
| 0x93 | ujl | ujl A | 3 |
| 0x94 | ujgeq | ujgeq A | 3 |
| 0x95 | ujleq | ujleq A | 3 |
| 0x96 | ujg | ujg A | 3 |
| 0x99 | halt | halt | 1 |
add,sub,smul,umul:- load:
R1 := [SP+3]; R2 := [SP] - exec:
R1 := R1 op R2 and set FLAGS; SP := SP + 3 - write back:
[SP] := R1
- load:
sdiv,udiv:- load:
R1 := [SP+3]; R2 := [SP] - exec:
R1 := R1 / R2 and set FLAGS; R2 := R1 % R2 - write back:
[SP+3] := R1; [SP] := R2
- load:
jump A:PC := Acmp:- load:
R1 := [SP+3]; R2 := [SP] - exec:
calc R1 - R2 and set FLAGS; SP := SP + 6
- load:
jeq A,jneq,jl,jleq,jg,jgeq:if op(FLAGS) then PC := Apush A:SP := SP - 3[SP] := [A]
pop A:[A] := [SP]SP := SP + 3
dup:SP := SP - 3[SP] := [SP + 3]
swap:[SP + 3] := [SP]; [SP] := [SP + 3]halt:FLAGS := HALT
Архитектура безадресной стековой модельной машины.
- Размер ячейки оперативной памяти: 2 байта.
- Размер адреса: 2 байтa.
- Арифметические вычисления производятся с одной ячейкой оперативной памяти.
- Код команды помещается в одну ячейку оперативной памяти
COP А. Размер значенияAв коде команды - 1 байт. - Регистры:
R1,R2,SP.
В регистры R1 и R2 загружаются данные из стека - ячеек оперативной
памяти по адресу [SP]. Результат вычислений записывается обратно на
вершину стека. При этом значение региста SP увеличивается или уменьшается
в зависимости от семантики команды.
Стек растет в сторону меньших адресов.
Попытка чтения данных за границами стека (например, команда POP при пустом
стеке) является ошибочной ситуацией и приведет к останову машины.
Команды перехода имеют относительную адресацию: регистр PC увеличивается или
уменьшается на значение операнда A с учетом знака.
Ввод и вывод
Ввод и вывод для mm-0 производится сразу на стек. При этомм
в директивах .input N и .output N аргумент N означает количество
элементов стека, а не адрес. Директивы заполняют и выгружают данные из стека
в соответсвии с порядком объявления.
Например, ввод 1 2 3 заполнит стек в таком порядке: 1 2 3 <- SP.
А директива .output 3 напечатает содержимое стека в таком порядке: 3 2 1.
add,sub,smul,umul:- load:
R1 := [SP + A]; R2 := [SP] - exec:
R1 := R1 op R2 and set FLAGS - write back:
[SP] := R1
- load:
sdiv,udiv:- load:
R1 := [SP + A]; R2 := [SP] - exec:
R1 := R1 / R2 and set FLAGS; R2 := R1 % R2; SP := SP - 1 - write back:
[SP + 1] := R1; [SP] := R2
- load:
jump:PC := PC + A-Aрасширяется до 16 битного числа с учетом знакаcmp:- load:
R1 := [SP + A]; R2 := [SP] - exec:
calc R1 - R2 and set FLAGS; SP := SP + 1
- load:
jeq,jneq,jl,jleq,jg,jgeq:if op(FLAGS) then PC := PC + Apush:SP := SP - 1[SP] := A-Aрасширяется до 16 битного числа с учетом знака
pop:SP := SP + A
dup:R1 := [SP + A]SP := SP - 1[SP] := R1
swap:[SP + A] := [SP]; [SP] := [SP + A]halt 00:FLAGS := HALT
Архитектура модельной машины с регистрами (registers)
- Размер ячейки оперативной памяти: 2 байта.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся со словом в 4 байта.
- Код команды занимает разное количество ячеек в зависимости от выполняемой
операции. Арифметические команды имеют формы регистр-регистр и регистр-память.
Команды регистр-регистр имеют формат
COP RA1 RA2и занимают 2 байта. Команды регистр-память имеют форматCOP R 0 Aи занимают 4 байта. Команды перехода имеют форматCOP 0 0 Aи занимают 4 байта. - Регистры:
R0-RF,S,S1.
Основное отличие этой машины от предыдущих - наличие адресуемых регистров
общего назначения R0-RF, используемых для арифметических
вычислений и адресации памяти.
S, S1 - неадресуемые регистры для работы АЛУ.
| Код команды | Мнемоник | Формат | Длина (в байтах) |
|---|---|---|---|
| 0x00 | load | load R 0 A | 4 |
| 0x01 | add | add R 0 A | 4 |
| 0x02 | sub | sub R 0 A | 4 |
| 0x03 | smul | smul R 0 A | 4 |
| 0x04 | sdiv | sdiv R 0 A | 4 |
| 0x05 | comp | comp R 0 A | 4 |
| 0x13 | umul | umul R 0 A | 4 |
| 0x14 | udiv | udiv R 0 A | 4 |
| 0x10 | store | store R 0 A | 4 |
| 0x20 | rmove | rmove RX RY | 2 |
| 0x21 | radd | radd RX RY | 2 |
| 0x22 | rsub | rsub RX RY | 2 |
| 0x23 | rsmul | rsmul RX RY | 2 |
| 0x24 | rsdiv | rsdiv RX RY | 2 |
| 0x25 | rcomp | rcomp RX RY | 2 |
| 0x33 | rumul | rumul RX RY | 2 |
| 0x34 | rudiv | rudiv RX RY | 2 |
| 0x80 | jump | jump 00 A | 4 |
| 0x81 | jeq | jeq 00 A | 4 |
| 0x82 | jneq | jneq 00 A | 4 |
| 0x83 | sjl | sjl 00 A | 4 |
| 0x84 | sjgeq | sjgeq 00 A | 4 |
| 0x85 | sjleq | sjleq 00 A | 4 |
| 0x86 | sjg | sjg 00 A | 4 |
| 0x93 | ujl | ujl 00 A | 4 |
| 0x94 | ujgeq | ujgeq 00 A | 4 |
| 0x95 | ujleq | ujleq 00 A | 4 |
| 0x96 | ujg | ujg 00 A | 4 |
| 0x99 | halt | halt 00 | 2 |
- register-memory
add,sub,smul,umul- formatop R 0 A:- load:
S := R; S1 := [A] - exec:
S := S op S1 and set FLAGS - write back:
R := S
- load:
- register-memory
sdiv,udiv- formatop R 0 A,R_next- регистр, следующий за регистромR; заRFследуетR0:- load:
S := R; S1 := [A] - exec:
S := S / S1 and set FLAGS; S1 := S % S1 - write back:
R, R_next := S, S1
- load:
- register-memory
comp R 0 A:- load:
S := S; S1 := [A] - exec:
S := S - S1 and set FLAGS
- load:
load R 0 A:R := [A]store R 0 A:[A] := R- register-register
radd,rsub,rsmul,rumul- formatop X Y:- load:
S := R_X; S1 := R_Y - exec:
S := S op S1 and set FLAGS - write back:
R_X := S
- load:
- register-register
rsdiv,rudiv- formatop X Y:- load:
S := R_X; S1 := R_Y - exec:
S := S / S1 and set FLAGS; S1 := S % S1 - write back:
R_X := S; R_next := S1
- load:
- register-register
rcomp X Y:- load:
S := R_X; S1 := R_Y - exec:
S := S - S1 and set FLAGS
- load:
- register-register
rmove X Y:R_X := R_Y jump A:PC := Ajeq,jneq,jl,jleq,jg,jgeq- formatop 00 A:if op(FLAGS) then PC := Ahalt:FLAGS := HALT
Архитектура модельной машины с модификацией адресов (modification).
- Размер ячейки оперативной памяти: 2 байта.
- Размер адреса: 2 байта.
- Арифметические вычисления производятся со словом в 4 байта.
- Код команды занимает разное количество ячеек в зависимости от выполняемой
операции. Арифметические команды имеют формы регистр-регистр и регистр-память.
Команды регистр-регистр имеют формат
COP RA1 RA2и занимают 2 байта. Команды регистр-память имеют форматCOP R M Aи занимают 4 байта. Команды перехода имеют форматCOP 0 0 Aи занимают 4 байта. - Регистры:
R0-RF,S,S1.
Является расширением модельной машины с регистрами.
Адресация данных теперь производится таким алгоритмом:
- Возьмем содержимое адресуемого регистра с номером
M(от 0x0 до 0xF):R_M. Если номер регистраMравен нулю, значениеR_0также равно нулю вне зависимости от содержимого регистраR0. - Добавим к нему адрес
A(от 0x0000 до 0xFFFF):R_M + A. - Возьмем остаток от деления этого адреса на 2^16:
(R_M + A) % 2^16. - Возьмем из ОЗУ данные по полученному адресу:
[R_M + A].
| Код команды | Мнемоник | Формат | Длина (в байтах) |
|---|---|---|---|
| 0x00 | load | load R M A | 4 |
| 0x01 | add | add R M A | 4 |
| 0x02 | sub | sub R M A | 4 |
| 0x03 | smul | smul R M A | 4 |
| 0x04 | sdiv | sdiv R M A | 4 |
| 0x05 | comp | comp R M A | 4 |
| 0x11 | addr | addr R M A | 4 |
| 0x13 | umul | umul R M A | 4 |
| 0x14 | udiv | udiv R M A | 4 |
| 0x10 | store | store R M A | 4 |
| 0x20 | rmove | rmove RX RY | 2 |
| 0x21 | radd | radd RX RY | 2 |
| 0x22 | rsub | rsub RX RY | 2 |
| 0x23 | rsmul | rsmul RX RY | 2 |
| 0x24 | rsdiv | rsdiv RX RY | 2 |
| 0x25 | rcomp | rcomp RX RY | 2 |
| 0x33 | rumul | rumul RX RY | 2 |
| 0x34 | rudiv | rudiv RX RY | 2 |
| 0x80 | jump | jump 0 M A | 4 |
| 0x81 | jeq | jeq 0 M A | 4 |
| 0x82 | jneq | jneq 0 M A | 4 |
| 0x83 | sjl | sjl 0 M A | 4 |
| 0x84 | sjgeq | sjgeq 0 M A | 4 |
| 0x85 | sjleq | sjleq 0 M A | 4 |
| 0x86 | sjg | sjg 0 M A | 4 |
| 0x93 | ujl | ujl 0 M A | 4 |
| 0x94 | ujgeq | ujgeq 0 M A | 4 |
| 0x95 | ujleq | ujleq 0 M A | 4 |
| 0x96 | ujg | ujg 0 M A | 4 |
| 0x99 | halt | halt 00 | 2 |
addr R M A:R := R_M + A- register-memory
add,sub,smul,umul- formatop R M A:- load:
S := R; S1 := [R_M + A] - exec:
S := S op S1 and set FLAGS - write back:
R := S
- load:
- register-memory
sdiv,udiv- formatop R M A,R_next- регистр, следующий за регистромR; заRFследуетR0:- load:
S := R; S1 := [R_M + A] - exec:
S := S / S1 and set FLAGS; S1 := S % S1 - write back:
R, R_next := S, S1
- load:
- register-memory
comp R M A:- load:
S := S; S1 := [R_M + A] - exec:
S := S - S1 and set FLAGS
- load:
load R M A:R := [R_M + A]store R M A:[R_M + A] := R- register-register
radd,rsub,rsmul,rumul- formatop X Y:- load:
S := R_X; S1 := R_Y - exec:
S := S op S1 and set FLAGS - write back:
R_X := S
- load:
- register-register
rsdiv,rudiv- formatop X Y:- load:
S := R_X; S1 := R_Y - exec:
S := S / S1 and set FLAGS; S1 := S % S1 - write back:
R_X := S; R_next := S1
- load:
- register-register
rcomp X Y:- load:
S := R_X; S1 := R_Y - exec:
S := S - S1 and set FLAGS
- load:
- register-register
rmove X Y:R_X := R_Y jump A:PC := R_M + Ajeq,jneq,jl,jleq,jg,jgeq- formatop 0 M A:if op(FLAGS) then PC := R_M + Ahalt:FLAGS := HALT