Skip to content

Latest commit

 

History

History
185 lines (141 loc) · 9.21 KB

README.md

File metadata and controls

185 lines (141 loc) · 9.21 KB

TuringCpu

Симулятор x86 подобного процессора на машине Тьюринга, использующий упрощённый синтаксис ассемблера на основе NASM. Программа, АЛУ, флаги, регистры, память и стек находятся на одной общей ленте единственной машины Тьюринга.

Симулятор процессора на МТ

Конфигурация

  • Произвольная точность вычислений (разрядность), по умолчанию 8 бит
  • Произвольное количество ячеек памяти, по умолчанию 16
  • Шесть регистров общего назначения: A, B, C, D, E, F
  • Флаги:
    • переполнения (OF)
    • знака (SF)
    • нуля (ZF)
    • переноса (CF)
  • поддержка чисел без знака и со знаком

Синтаксис

  • Каждая инструкция располагается на отдельной строке
  • Метки должны начинаться с буквы или точки (.) и заканчиваться двоеточием
  • Комментарий начинается с символа ;
  • Адреса заключаются в квадратные скобки [address] и обозначает номер ячейки памяти
  • В качестве адреса может быть положительная константа ([12]) или регистр общего назначения ([A])
  • Операндами команд могут быть регистры общего назначения, константы, адреса или метки

Общий вид строки программы: метка: инструкция аргументы ; комментарий

Допустимые форматы констант:

  • Двоичный: 0b1111011 или 1111011b
  • Восьмеричный: 0o173
  • Десятичный: 123 или 123d (в том числе со знаком -123)
  • Шестнадцатиричный: 0x7B

Команда MOV

Помещает содержимое аргумента arg2 в аргумент arg1

Допустимая конфигурация аргументов:

  • MOV регистр, регистр/константа/адрес
  • MOV адрес, регистр/константа

Синтаксис: MOV arg1, arg2

Стековые инструкции

Команда PUSH - добавить в стек

Помещает переданное значение в стек

Синтаксис: PUSH arg

Команда POP - извлечь из стека

Извлекает значение из стека и помещает его на переданный регистр. Если стек пуст, происходит ошибка.

Синтаксис: 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

Команда CMP

Выполняет вычитание двух чисел. Результат никуда не записывается, модифицируются значения флагов OF, SF, ZF и CF

Синтаксис: CMP reg, arg

Команда TEST

Выполняет логическое И. Результат никуда не записывается, модифицируются значения флагов ZF и SF и сбрасываются состояния флагов OF и CF

Синтаксис: TEST reg, arg

Переходы

Безусловный переход (JMP)

Производит передачу управления на инструкцию по переданному адресу. В качестве адреса может использовать метка, константа или регистр.

Синтаксис: 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 ≥)

Вызов подпрограммы - CALL

В стек помещается адрес следующей инструкции, используемый впоследствии командой RET, и выполняется переход по указанному адресу. В качестве адреса, как и в командах переходов, может использоваться метка, константа или регистр.

Синтаксис: CALL address

Выход из подпрограммы - RET

Извлекает из стека адрес возврата и выполняет переход на инструкцию по извлечённому адресу.

Синтаксис: RET

Команда HLT

Немедленно завершает работу процессора

Синтаксис: 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 ; выходим из подпрограммы

Скриншоты работы

Пример 1 Пример 2 Пример 3 Пример 4