Симулятор x86 подобного процессора на машине Тьюринга, использующий упрощённый синтаксис ассемблера на основе NASM. Программа, АЛУ, флаги, регистры, память и стек находятся на одной общей ленте единственной машины Тьюринга.
- Произвольная точность вычислений (разрядность), по умолчанию 8 бит
- Произвольное количество ячеек памяти, по умолчанию 16
- Шесть регистров общего назначения:
A
,B
,C
,D
,E
,F
- Флаги:
- переполнения (
OF
) - знака (
SF
) - нуля (
ZF
) - переноса (
CF
)
- переполнения (
- поддержка чисел без знака и со знаком
- Каждая инструкция располагается на отдельной строке
- Метки должны начинаться с буквы или точки (
.
) и заканчиваться двоеточием - Комментарий начинается с символа
;
- Адреса заключаются в квадратные скобки
[address]
и обозначает номер ячейки памяти - В качестве адреса может быть положительная константа (
[12]
) или регистр общего назначения ([A]
) - Операндами команд могут быть регистры общего назначения, константы, адреса или метки
Общий вид строки программы: метка: инструкция аргументы ; комментарий
- Двоичный:
0b1111011
или1111011b
- Восьмеричный:
0o173
- Десятичный:
123
или123d
(в том числе со знаком-123
) - Шестнадцатиричный:
0x7B
Помещает содержимое аргумента arg2
в аргумент arg1
Допустимая конфигурация аргументов:
MOV регистр, регистр/константа/адрес
MOV адрес, регистр/константа
Синтаксис: MOV arg1, arg2
Помещает переданное значение в стек
Синтаксис: PUSH arg
Извлекает значение из стека и помещает его на переданный регистр. Если стек пуст, происходит ошибка.
Синтаксис: POP reg
Модифицируют значения флагов OF
, SF
, ZF
и CF
- Сложение:
ADD reg, arg
- Вычитание:
SUB reg, arg
- Умножение:
MUL reg, arg
(без поддежркиOF
пока) - Деление:
DIV reg, arg
(без поддежркиOF
пока) - Инкремент:
INC reg
- Декремент:
DEC reg
- Изменение знака:
NEG reg
Модифицируют значение флагов ZF
и SF
. Флаги OF
и CF
сбрасываются
- И:
AND reg, arg
- ИЛИ:
OR reg, arg
- Исключающее ИЛИ:
XOR reg, arg
- НЕ:
NOT reg
Модифицируют значение флагов SF
, ZF
и CF
. Флаг OF
сбрасывается
- Сдвиг влево:
SHL reg, arg
- Сдвиг вправо:
SHR reg, arg
- Циклический сдвиг влево:
ROL reg
- Циклический сдвиг вправо:
ROR reg
Выполняет вычитание двух чисел. Результат никуда не записывается, модифицируются значения флагов OF
, SF
, ZF
и CF
Синтаксис: CMP reg, arg
Выполняет логическое И. Результат никуда не записывается, модифицируются значения флагов ZF
и SF
и сбрасываются состояния флагов OF
и CF
Синтаксис: TEST reg, arg
Производит передачу управления на инструкцию по переданному адресу. В качестве адреса может использовать метка, константа или регистр.
Синтаксис: JMP address
Работают аналогично безусловному переходу, предварительно проверяя некоторое условие:
JO
- перейти, если переполнение (OF = 1
)JNO
- перейти, если нет переполнения (OF = 0
)JS
- перейти, если знак равен 1 (SF = 1
)JNS
- перейти, если знак равен 0 (SF = 0
)JZ
- перейти, если ноль (ZF = 1
)JNZ
- перейти, если не ноль (ZF = 0
)JC
- перейти, если перенос (CF = 1
)JNC
- перейти, если нет переноса (CF = 0
)JE
- перейти, если равно (ZF = 1
)JNE
- перейти, если не равно (ZF = 0
)
JB
- перейти, если меньше (CF = 1
)JBE
- перейти, если меньше или равно (CF = 1
илиZF = 1
)JA
- перейти, если больше (ZF = 0
иCF = 0
)JAE
- перейти, если больше или равно (CF = 0
)JNB
- перейти, если не меньше (not <
)JNBE
- перейти, если не меньше или равно (not ≤
)JNA
- перейти, если не больше (not >
)JNAE
- перейти, если не больше или равно (not ≥
)
JL
- перейти, если меньше (SF ≠ OF
)JLE
- перейти, если меньше или равно (ZF = 1
илиSF ≠ OF
)JG
- перейти, если больше (ZF = 0
иSF = OF
)JGE
- перейти, если больше или равно (SF = OF
)JNL
- перейти, если не меньше (not <
)JNLE
- перейти, если не меньше или равно (not ≤
)JNG
- перейти, если не больше (not >
)JNGE
- перейти, если не больше или равно (not ≥
)
В стек помещается адрес следующей инструкции, используемый впоследствии командой RET, и выполняется переход по указанному адресу. В качестве адреса, как и в командах переходов, может использоваться метка, константа или регистр.
Синтаксис: CALL address
Извлекает из стека адрес возврата и выполняет переход на инструкцию по извлечённому адресу.
Синтаксис: RET
Немедленно завершает работу процессора
Синтаксис: HLT
JMP start
.loop:
CALL fibonacci
DEC A ; уменьшаем номер
JNZ .loop
MOV A, B ; записывем результат в А
HLT
start:
MOV A, 11 ; номер числа Фибоначчи
XOR B, B
MOV C, 0x1
CMP A, 12
CMP A, 11
CMP A, 10
JMP .loop
; функция вычисления следующего числа Фибоначчи
; два соседних члена последовательности располагаются
; в регистрах C и B соответственно
; результат записывается в регистр B
fibonacci:
PUSH B ; сохраняем предыдущий член последовательности
ADD B, C ; вычисляем новый
POP C ; возвращаем сохранённый на место предыдущего
RET ; выходим из подпрограммы