Skip to content
Snippets Groups Projects
README.md 17.9 KiB
Newer Older
vslutov's avatar
vslutov committed
# modelmachine
Model machine emulator
vslutov's avatar
vslutov committed

vslutov's avatar
vslutov committed
## TODO

vslutov's avatar
vslutov committed
* УМ-П (с переменным форматом команд)
* УМ-1 (одноадресная)
* УМ-С (стековая)
* УМ-Р (решистровая)
* УМ с модификацией адресов ???

* Работа с плавающей запятой
vslutov's avatar
vslutov committed
* Подумать о mock в тестах
vslutov's avatar
vslutov committed
* Подумать о команде остановки halt
vslutov's avatar
vslutov committed
* Добавить howto install and use
* Переделать документацию модулей
vslutov's avatar
vslutov committed
* ГУИ
vslutov's avatar
vslutov committed

vslutov's avatar
vslutov committed
## Модельная машина

Модельная машина - это чистая архитектурная концепция, позволяющая понять
логику функционирования центральных процессоров. По своей структуре она близка
к компьютерам первого поколения. Подробнее читайте по ссылкам внизу.

vslutov's avatar
vslutov committed
## Quickstart

Установка пакета происходит командой:

    # python3 -m pip install --upgrade modelmachine

После этого вам станет доступна консольная команда `modelmachine`.
Для проверки сделайте `modelmachine test`. Будет выполнена серия тестов,
все тесты должны закончиться успехом.

Посмотрите примеры в папке <samples>, по их образу можно начинать писать
программы для модельных машин. Запуск программы делается командой:

    $ modelmachine run program.mmach

### Пример

    bordachenkova_mm3

    [config]
    input = 0x100,0x101
    output = 0x103

    [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

    [input]
    -123 456

vslutov's avatar
vslutov committed
* Первая строчка - обязательное название архитектуры. Список поддерживаемых
vslutov's avatar
vslutov committed
  архитектур смотри ниже.
* После этого должна идти секция `config`, описывающая ячейки памяти,
  по которым нужно производить ввод и вывод.
* После этого секция кода, содержащая набор 16-ричных чисел, записываемых в
  память модельной машины. Пропускать часть машинного слова нельзя.
  Рекомендуется писать по одному машинному слову в строке, по желанию
  разбивая разряды на части пробелами.
* Все, что идет после символа `;` - комментарий.
* Пустые строки игнорируются.
* После этого идет секция ввода - несколько чисел, разделенных пробельными
  символами. Их число должно совпадать с числом ячеек для ввода в параметре
  `input` в секции `config`.
* По окончании работы на экран будут напечатаны десятичные числа со знаком,
  лежащие в ячейках, перечисленных в параметре `output` в секции `config`.

vslutov's avatar
vslutov committed
## Внутреннее устройство

Данная реализация модельной машины состоит из классов, разбитых на
файлы-модули:

* `memory.py` - память; делится на два класса: `регистровая` и
  `оперативная`; оперативная делится на `little-endian` и `big-endian`
* `numeric.py` - целочисленная арифметика с фиксированным числом
  двоичных знаков
* `alu.py` - арифметико-логическое устройство, работает с четко
  специализированными регистрами: `R1`, `R2`, `S`, `FLAGS` и `IP`.
vslutov's avatar
vslutov committed
* `cu.py` *в процессе реализации* - контролирующее устройство, выполняющее
vslutov's avatar
vslutov committed
  считывание команд из памяти и запускающее необходимые методы в
  арифметико-логическом устройстве
* `io.py` - устройство ввода-вывода
* `cpu.py` - финальное объединение составляющих устройств в единое целое

Здесь дано поверхностное описание модулей. За более подробным
vslutov's avatar
vslutov committed
обращайтесь к документации конкретных модулей и их исходным кодам.
vslutov's avatar
vslutov committed

### memory.py

`AbstractMemory` - класс абстрактной памяти, предоставляющий интерфейс для
надежной связи частей компьютера. Основные методы: `fetch` и `put`, которые
vslutov's avatar
vslutov committed
принимают на вход адрес в памяти и количество битов, с которыми нужно работать,
vslutov's avatar
vslutov committed
количество должно быть кратно размеру ячейки (слова). Строго
vslutov's avatar
vslutov committed
рекомендуется их использовать везде.
vslutov's avatar
vslutov committed

`RandomAccessMemory` - класс, реализующий память прямого доступа. При
инициализации указывается размер машинного слова и количество этих слов. Если
`is_protected=True`, то при попытке считывания из неинициализированной ячейки
будет выброшено исключение, иначе, метод `fetch` вернет нуль.

vslutov's avatar
vslutov committed
`RegisterMemory` - класс, реализующий регистровую память. Метод `add_register`
добавляет регистр определенного размера или проверяет, что уже добавленный
регистр имеет правильный размер.
vslutov's avatar
vslutov committed

### numeric.py

Класс Integer реализует целочисленную арифметику фиксированной длины.
Поддерживаемые операторы: `+`, `-`, `*`, `/`, `%`, `==`, `!=`. Плюс методы
vslutov's avatar
vslutov committed
`get_value` и `get_data`. Округление при делении производится в сторону нуля.
vslutov's avatar
vslutov committed

### alu.py

Арифметико-логическое устройство работает с четко специализированными
регистрами:

* `R1`, `R2`, `S` для арифметических операций.
vslutov's avatar
vslutov committed
* `FLAGS` для хранения флагов состояния.
* `IP` *только* для пересылки туда адреса из регистра `R1` при условных
  переходах.
vslutov's avatar
vslutov committed

Схема работы:

vslutov's avatar
vslutov committed
* Арифметические команды: `add`, `sub`, `smul`, `sdiv`, `umul`, `udiv`,
  `sdivmod`, `udivmod`. За исключением команд `divmod` арифметические
  команды работают следующим образом: `S := R1 op R2`.
vslutov's avatar
vslutov committed
  Плюс в зависимости от результата выставляется регистр `FLAGS` - комбинация
  флагов CF, OF, SF и ZF.
* `add` и `sub` - сложение и вычитание соответсвенно.
* `smul` и `sdiv` - знаковое умножение и деление соответсвенно.
* `umul` и `udiv` - беззнаковое умножение и деление соответсвенно.
vslutov's avatar
vslutov committed
* `sdivmod` и `udivmod` - знаковое и беззнаковое соответственно деление с
  остатком. `S := R1 / R2; R1 := R1 % R2`.
vslutov's avatar
vslutov committed
* Команда пересылки `move`: `S := R1`.
* Команды безусловного перехода `jump` и условного перехода `cond_jump`
  работают по схеме `IP := R1`, режим работы `cond_jump` зависит от того,
  какие дополнительные аргументы будут переданы.
* Команда останова `halt` просто выставляет флаг остановки HALT в
  регистре флагов

### cu.py

Управляющее устройство.

#### AbstractControlUnit

Обычно управляющее устройство работает по схеме:

1. `fetch_and_decode` - загрузка и расшифровка очередной команды.
vslutov's avatar
vslutov committed
   Содержимое ячейки оперативной памяти с адресом записанным
vslutov's avatar
vslutov committed
   в регистре `IP` загружается в регистр `IR`, затем из него извлекается
   код операции и адреса операндов, затем счетчик `IP` увеличивается на
   длину только что считанной команды.
2. `load` - данные по только что считанным адресам загружаются в регистры
   процессора `R1` и `R2`
3. `execute` - в зависимости от кода операции в арифметико-логическом
   устройстве запускается та или иная схема вычислений.
4. `write_back` - результат вычислений записывается куда полагается (например,
vslutov's avatar
vslutov committed
   по одному из адресов считанных в начале).
vslutov's avatar
vslutov committed

Все эти методы поддерживаются в `AbstractControlUnit`.
Также в нем написаны использующие их методы, являющиеся интерфейсом
устройства управления:

* `step` - сделать один шаг, описанный алгоритмом выше.
* `get_status` - вернуть статус процессора (выполняется/остановлен).
  Остановка производится командой останова `halt`.
* `run` - выполнять один шаг за другим, пока процессор не будет остановлен.

Далее, наследники `AbstractControlUnit` определяют первые 4 метода.

### io.py

Устройство ввода-вывода.

* При инициализации устанавливается адрес с которого нужно загружать
  программы пользователя.
* Метод `load_source` загружает последовательность шеснадцатиричных слов
  по указанному адресу.
* Метод `load_data` загружает данные (полученные из строки чисел)
  по данным адресам.
* Методы `get_int` и `put_int` работают с содержимым одной ячейки оперативной
  памяти.

### cpu.py

Финальная сборка всех составных устройств в единое целое.

* Поддерживается доступ к составным устройствам. Например, доступ
  к устройству ввода/вывода можно получить через `cpu.io_unit`,
  к регистрам через `cpu.registers` и так далее.
* `load_program` - загрузка программы, конфигурации и данных в оперативную
  память.
vslutov's avatar
vslutov committed
* `print_result` - печать результата работы программы.
* `run_file` - загрузка, исполнение и печать результата.
vslutov's avatar
vslutov committed

## Поддерживаемые архитектуры

### Как добавить новую архитектуру?

1. Выписать все команды устройстройства и их коды.
2. Добавить их в таблицу ниже и описание еще ниже.
3. Добавить новый класс устройства управления на основе существующего.
4. Добавить новый класс CPU использующий это устройство управления.
5. Добавить тесты для обоих этих классов в файлы `tests/test_cu.py` и
   `tests/test_cpu.py`.
6. Добавить примеры в папку `samples`.
7. Прислать pull request.

### Таблица команд модельных машин
vslutov's avatar
vslutov committed

vslutov's avatar
vslutov committed
|OPCODE|mm-3|mm-2|
vslutov's avatar
vslutov committed
|:-----|:--:|:--:|
|0x00  |move|move|
|0x01  |add |add |
|0x02  |sub |sub |
|0x03  |smul|smul|
|0x04  |sdiv|sdiv|
|0x05  |    |comp|
|0x13  |umul|umul|
|0x14  |udiv|udiv|
|0x80  |jump|jump|
|0x81  | == | == |
|0x82  | != | != |
|0x83  |<  s|<  s|
|0x84  |>= s|>= s|
|0x85  |<= s|<= s|
|0x86  |>  s|>  s|
|0x93  |<  u|<  u|
|0x94  |>= u|>= u|
|0x95  |<= u|<= u|
|0x96  |>  u|>  u|
|0x99  |halt|halt|

vslutov's avatar
vslutov committed
На самом деле операция `div` запускает в АЛУ схему `divmod`.

vslutov's avatar
vslutov committed
Знаки сравнения в таблице означают команды условного перехода. Как они
работают читайте в книге *[1]* и ниже по тексту.

vslutov's avatar
vslutov committed
|Мнемонический код|Обозначение выше|Расшифровка/описание             |
|:----------------|:--------------:|:--------------------------------|
|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         |
vslutov's avatar
vslutov committed

### bordachenkova_mm3
vslutov's avatar
vslutov committed

vslutov's avatar
vslutov committed
* Размер ячейки оперативной памяти: 7 байт.
* Размер адреса: 2 байта.
* Арифметические вычисления производятся с одной ячейкой оперативной памяти.
* Код команды помещается в одну ячейку оперативной памяти `КОП А1 А2 А3`.
vslutov's avatar
vslutov committed
Действия процессора для арифметических инструкций (`add`, `sub`,
`smul`, `sdiv`, `umul`, `udiv`) `КОП A1 A2 A3`:
vslutov's avatar
vslutov committed

1. Загрузить содержимое ячейки оперативной памяти с адресом `А1` в
vslutov's avatar
vslutov committed
   регистр `R1` (`R1 := [A1]`).
vslutov's avatar
vslutov committed
2. Загрузить содержимое ячейки оперативной памяти с адресом `А2` в
vslutov's avatar
vslutov committed
   регистр `R2` (`R2 := [A2]`).
vslutov's avatar
vslutov committed
3. Запустить в АЛУ схему, реализующую операцию, задаваемую `КОП`.
vslutov's avatar
vslutov committed
4. Записать результат из регистра `S` в ячейку оперативной памяти с
   адресом `А3`.
   Если выполняется операция деления, в оперативную память записываются
   два результата: частное – в ячейку с адресом `А3`, остаток – в следующую
   ячейку, по адресу `(А3+1) mod 16^4`.

vslutov's avatar
vslutov committed
* `jump A1 A2 A3`: `IP := A3`
vslutov's avatar
vslutov committed
* Условные переходы: сравниваются `R1` и `R2`, в зависимости от результата
  происходит `IP := A3`.
* Команда пересылки `move`: [A3] := R1.
vslutov's avatar
vslutov committed
### bordachenkova_mm2
vslutov's avatar
vslutov committed
* Размер ячейки оперативной памяти: 5 байт.
* Размер адреса: 2 байта.
* Арифметические вычисления производятся с одной ячейкой оперативной памяти.
* Код команды помещается в одну ячейку оперативной памяти `КОП А1 А2`.
vslutov's avatar
vslutov committed

Действия для арифметических команд `add`, `sub`, `smul`, `sdiv`, `umul`,
`udiv`:

1. R1 := [A1], R2 := [A2]
vslutov's avatar
vslutov committed
2. Запустить в АЛУ схему, реализующую операцию, задаваемую `КОП`.
vslutov's avatar
vslutov committed
3. [A1] := S

Действия для команды сравнения `cmp`:

1. R1 := [A1], R2 := [A2]
2. Запустить в АЛУ схему `sub` (в том числе выставить регистр `FLAGS`)

* `jump A1 A2`: `IP := A2`
vslutov's avatar
vslutov committed
* Условные переходы делаются исходя из регистра `FLAGS`
vslutov's avatar
vslutov committed
* `move A1 A2`: `[A1] := [A2]`
* Команда останова `halt` взводит флаг `HALT` в регистре `FLAGS`

vslutov's avatar
vslutov committed
## References

vslutov's avatar
vslutov committed
1. E. А. Бордаченкова - "Модельные ЭВМ" <http://al.cs.msu.su/files/ModComp.pdf>
2. Е. А. Бордаченкова - "Архитектура ЭВМ. Учебные машины. Методическое пособие"
   <http://al.cs.msu.su/files/bordachenkova.architecture.model.machines.2010.doc>
3. В. Г. Баула - "Введение в архитектуру ЭВМ и системы программирования"
   <http://arch.cs.msu.ru/Page2.htm>
4. <http://cmcmsu.no-ip.info/1course/um3.command.set.htm>