{"id":24938460,"url":"https://github.com/armemius/processoremulator","last_synced_at":"2025-03-28T17:24:27.623Z","repository":{"id":273565875,"uuid":"863567121","full_name":"Armemius/ProcessorEmulator","owner":"Armemius","description":"Educational project for implementing basic stack processor","archived":false,"fork":false,"pushed_at":"2025-01-21T16:42:36.000Z","size":530,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-02T17:57:52.769Z","etag":null,"topics":["cli","itmo","study"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Armemius.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-26T14:12:56.000Z","updated_at":"2025-01-21T16:42:39.000Z","dependencies_parsed_at":"2025-01-21T17:36:53.660Z","dependency_job_id":"355799d2-8dda-4080-bb9a-854cff6badf0","html_url":"https://github.com/Armemius/ProcessorEmulator","commit_stats":null,"previous_names":["armemius/processoremulator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armemius%2FProcessorEmulator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armemius%2FProcessorEmulator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armemius%2FProcessorEmulator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Armemius%2FProcessorEmulator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Armemius","download_url":"https://codeload.github.com/Armemius/ProcessorEmulator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246068281,"owners_count":20718503,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","itmo","study"],"created_at":"2025-02-02T17:58:14.647Z","updated_at":"2025-03-28T17:24:27.602Z","avatar_url":"https://github.com/Armemius.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Эмулятор стекового процессора\n\n## Язык программирования\n\nДля удобства работы был написан транслятор для ассемблер-подобного\nязыка.\nПри разработке синтаксиса и семантики учитывались особенности архитектуры\nпроцессора.\n\n### Описание синтаксиса в форме Бэкуса-Наура\n\n```text\n\u003cprogram\u003e ::= \u003cstatement\u003e | \u003cstatement\u003e \u003cendl\u003e \u003cprogram\u003e\n\n\u003cstatement\u003e ::= \u003cdeclaration\u003e | \u003ccomment\u003e | \u003cdeclaration\u003e \u003ccomment\u003e\n\n\u003cdeclaration\u003e ::= \u003cinstruction\u003e | \u003csection\u003e | \u003clabel\u003e | \u003clabel\u003e \u003cinstruction\u003e\n\n\u003cinstruction\u003e ::= \u003copcode\u003e | \u003copcode\u003e \u003coperands\u003e\n\n\u003coperands\u003e ::= \u003coperand\u003e | \u003coperand\u003e ',' \u003coperands\u003e\n\n\u003coperand\u003e ::= \u003cidentifier\u003e | \u003cimmediate\u003e\n\n\u003cimmediate\u003e ::= \u003cnumber\u003e | \u003cchar\u003e | \u003cstring\u003e\n\n\u003csection\u003e ::= '.section' \u003csection_identifier\u003e\n\n\u003csection_identifier\u003e ::= 'text' | 'data' | 'devices'\n\n\u003clabel\u003e ::= \u003cidentifier\u003e ':'\n\n\u003ccomment\u003e ::= ';' \u003cstring\u003e\n\n\u003copcode\u003e ::= 'push' | 'pop' | 'inc' | 'dec' | 'swap' | 'dup' | 'nop' | 'jmp' |\n             'call' | 'ret' | 'halt' | 'iret' | 'ei' | 'di' | 'in' | 'out' |\n             'add' | 'sub' | 'mul' | 'div' | 'and' | 'or' | 'xor' | 'not' | \n             'neg' | 'ld' | 'st' | 'cmp' | 'jz' | 'je' | 'jnz' | 'jg' | \n             'jge' | 'jl' | 'jle' | 'res' | 'byte' | 'char' | 'str' | 'shl' \n             | 'shr' | 'rol' | 'ror' | 'addr'\n\n\u003cnumber\u003e ::= \u003cdigit\u003e | \u003cdigit\u003e \u003cnumber\u003e\n\n\u003cdigit\u003e ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'\n\n\u003cchar\u003e ::= \"'\" \u003ccharacter\u003e \"'\"\n\n\u003ccharacter\u003e ::= \u003cletter\u003e | \u003cdigit\u003e | \u003csymbol\u003e\n\n\u003cstring\u003e ::= '\"' \u003ccharacters\u003e '\"'\n\n\u003ccharacters\u003e ::= \u003ccharacter\u003e | \u003ccharacter\u003e \u003ccharacters\u003e\n\n\u003cidentifier\u003e ::= \u003cletter\u003e | \u003cidentifier\u003e \u003cletter\u003e | \u003cidentifier\u003e \u003cdigit\u003e\n\n\u003cletter\u003e ::= 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' \n             | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' \n             | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' \n             | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | \n             'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'\n\n\u003csymbol\u003e ::= '!' | '@' | '#' | '$' | '%' | '^' | '\u0026' | '*' | '(' | ')' | '-' \n             | '+' | '=' | '{' | '}' | '[' | ']' | ':' | ';' |\n\n\u003cendl\u003e ::= '\\n' | '\\n\\r'\n```\n\n### Описание семантики\n\n#### Описание команд\n\n- `push [number | label]` -- помещает значение на вершину стека.\n- `pop` -- извлекает значение со стека.\n- `pushf` -- помещение регистра состояния на стек\n- `popf` -- снятие и запись со стека содержимого регистра состояния\n- `inc` -- увеличивает значение на вершине стека на 1.\n- `dec` -- уменьшает значение на вершине стека на 1.\n- `swap` -- меняет местами два значения на вершине стека.\n- `dup` -- дублирует значение на вершине стека.\n- `nop` -- ничего не делает, команда для отладки.\n- `call [label]` -- вызов подпрограммы.\n- `ret` -- возврат из подпрограммы, переход по адресу лежащему на вершине стека\n  и извлечение операнда из него.\n- `halt` -- завершение программы.\n- `iret` -- завершение обработки прерывания, возврат из прерывания.\n- `ei` -- разрешение прерываний.\n- `di` -- запрет прерываний.\n- `add` -- сложение двух верхних элементов стека и запись результата на вершину\n  стека, операнды убираются со стека.\n- `sub` -- вычитание второго элемента стека сверху из первого и запись\n  результата на вершину стека, операнды убираются\n  со стека.\n- `mul` -- умножение двух верхних элементов стека и запись результата на вершину\n  стека, операнды убираются со стека.\n- `div` -- целочисленное деление второго элемента стека сверху на первый и\n  запись результата на вершину стека, операнды\n  убираются со стека.\n- `and` -- побитовое И двух верхних элементов стека и запись результата на\n  вершину стека, операнды убираются со стека.\n- `or` -- побитовое ИЛИ двух верхних элементов стека и запись результата на\n  вершину стека, операнды убираются со стека.\n- `xor` -- побитовое исключающее ИЛИ двух верхних элементов стека и запись\n  результата на вершину стека, операнды\n  убираются со стека.\n- `not` -- побитовое отрицание верхнего элемента стека и запись результата на\n  вершину стека, операнд убирается со стека.\n- `neg` -- арифметическое отрицание верхнего элемента стека и запись результата\n  на вершину стека, операнд убирается со\n  стека.\n- `shl` -- побитовый сдвиг верхнего элемента стека влево и замена вершины стека\n  на полученное значение.\n- `shr` -- побитовый сдвиг верхнего элемента стека вправо и замена вершины стека\n  на полученное значение.\n- `rol` -- циклический сдвиг верхнего элемента стека влево и замена вершины\n  стека на полученное значение.\n- `ror` -- циклический сдвиг верхнего элемента стека вправо и замена вершины\n  стека на полученное значение.\n- `ld` -- загрузка из памяти ячейки по адресу, записанному в вершине и запись\n  содержимого на вершину стека, операнды\n  убираются со стека.\n- `st` -- сохранение в память второго значения от вершины стека по адресу\n  первого.\n- `cmp` -- вычитание второго элемента стека сверху из первого и запись\n  результата на вершину стека, операнды не\n  убираются со стека.\n- `jmp [label]` -- безусловный переход.\n- `jz [label]` -- переход, если значение на вершине стека равно нулю, значение\n  убирается с вершины стека.\n- `je [label]` -- переход, если значение на вершине стека равно нулю, значение\n  убирается с вершины стека.\n- `jnz [label]` -- переход, если значение на вершине стека не равно нулю,\n  значение убирается с вершины стека.\n- `jg [label]` -- переход, если значение на вершине стека больше нуля, значение\n  убирается с вершины стека.\n- `jge [label]` -- переход, если значение на вершине стека больше или равно\n  нулю, значение убирается с вершины стека.\n- `jl [label]` -- переход, если значение на вершине стека меньше нуля, значение\n  убирается с вершины стека.\n- `jle [label]` -- переход, если значение на вершине стека меньше или равно\n  нулю, значение убирается с вершины стека.\n- `res [number]` -- резервирование N байтов в памяти.\n- `byte [byte 1] (, byte 2(, byte 3 ...))` -- запись набора байтов в память.\n- `char [char 1] (, char 2(, char 3 ...))` -- запись строковых литералов в\n  память.\n- `str [string]` -- запись строки в память.\n\n#### Особенности реализации\n\nПрограмма состоит из нескольких секций:\n\n- Секция `text` содержит исполняемый код, в этой секции нельзя использовать\n  команды резервирования памяти.\n- Секция `data` содержит данные для программы, в этой секции можно использовать\n  команды резервирования памяти.\n\nСекции определяется от объявления до конца файла или следующего объявления\nсекции, по умолчанию файл полностью является\nсекцией `text`.\n\nПрограмма организована в виде последовательности инструкций. Инструкции\nвыполняются последовательно, одна за другой.\nКаждая инструкция может не содержать операндов или\nсодержать один, или несколько операндов.\n\n##### Комментарии\n\nКомментарии начинаются с символа `;` и продолжаются до конца строки.\n\n```asm\n; sample comment 1\npush 0x1337 ; sample comment 2\n```\n\n##### Числа\n\nЧисла могут записывать в шестнадцатеричной, десятичной или двоичной системе\nсчисления. Числа в шестнадцатеричной системе\nначинаются с префикса `0x`, в двоичной с `0b`.\n\n```asm\npush 0x1337 ; hexadecimal\npush 0b1010 ; binary\npush 42     ; decimal\n```\n\n##### Строки\n\nФормат строк - C-style, конец строки обозначается нуль-терминатором.\n\nСтроки заключаются в двойные кавычки, нуль-терминатор не ставится автоматически,\nнеобходимо явно его прописывать.\n\n```asm\n.section data\n\nsample_string_1:\n    str \"Hello, world!\\0\"\n    ; null terminator is added in string declaration\nsample_string_2:\n    str \"Hello, world!\"\n    byte 0\n    ; null terminator is added via appended zero byte\nsample_string_3:\n    byte 61, 62, 63, 0\n    ; \"abc\\0\" string declaration via bytes sequence\n```\n\n##### Области видимости\n\nОперации со стеком можно выполнять из любой точки программы, определение данных\nосуществляется только в секции `data`,\nвидимость меток глобальная.\n\n##### Память\n\n- Память распределяется статически на этапе трансляции\n- При определении данных в секции `data` память выделяется по адресу метки и\n  последующие данные записываются в память по\n  порядку,\n  при заполнении ячейки памяти, запись продолжается со следующей ячейки. При\n  определении новой метки память выделяется\n  со следующего свободного адреса.\n- Порядок данных в памяти - big-endian\n\n```asm\n.section data\n\n.string:\n    str \"abc\\0\"\n.array_1:\n    byte 0x12, 0x34, 0x5\n.array_1:\n    byte 0x1, 0x3, 0x3, 0x7\n\n; Вид памяти после трансляции\n; (условное представление в 16-разрядной сетке)\n;\n; +------+--------+------------------+\n; | ADDR | VALUE  |     COMMENT      |\n; +------+--------+------------------+\n; | 0xN0 | 0x6162 | \u003c- метка string  |\n; | 0xN1 | 0x6300 |                  |\n; | 0xN2 | 0x1234 | \u003c- метка array_1 |\n; | 0xN3 | 0x0500 |                  |\n; | 0xN4 | 0x0103 | \u003c- метка array_2 |\n; | 0xN5 | 0x0307 |                  |\n; +------+--------+------------------+\n```\n\n##### Типизация, виды литералов\n\nЛитералы могут быть представлены в виде чисел и меток, метки впоследствии\nконвертируются в адреса и интерпретируются\nкак числа. Все строковые литералы на моменте трансляции кодируются при помощи\nтаблицы ASCII и интерпретируются как\nчисла.\nТипизация отсутствует и пользователь может работать с данными в зависимости от\nего интерпретации и выполнять с ними\nлюбые\nоперации без каких-либо ограничений.\n\n## Организация памяти\n\n- Архитектура Фон-Неймана\n- Линейное адресное пространство\n- 16'777'216 (0x1000000) ячеек памяти, каждая ячейка размером 4 байта (32 бит),\n  64Мб в сумме\n- Инструкции, данные, векторы прерываний, их обработчики и подпрограммы\n  находятся в одном адрессном пространстве\n- Взаимодействие с данными осуществляется через стек и операции\n  загрузки/сохранения (`ld`/`st`) в память\n- Стек хранится в одном адресном пространстве с инструкциями и данными\n- Стек растет в сторону уменьшения адресов начинаю с адреса `0x1000000`\n- Адресация может быть прямой абсолютной и косвенной:\n  - Прямая абсолютная адресация - адрес явно указан в инструкции\n  - Косвенная адресация - адрес рассчитывается по сдвигу относительно текущей\n    команды, используя значение счётчика\n    команд\n- Динамически считываемые данные можно помещать на стек, либо в заранее\n  зарезервированный буфер\n- Инициализация устройств находится в начале адресной сетки, занимает по две\n  ячейки памяти на устройство и имеет следующий формат\n  - Вторая ячейка -- 8 бит для флагов состояния и 24 бита адрес обработчика\n    прерывания\n  - Первая ячейка -- 8 бит для указания размера буфера и 24 бита для адреса\n    буфера для ввода/вывода устройства\n  - Флаги содержат информацию о том используются ли прерывания для устройства,\n    включено ли устройство и его готовность\n    - 1-й бит -- флаг работы устройства\n    - 2-й бит -- флаг прерывания\n    - 3-15й биты -- зарезервированы\n    - Старший бит -- флаг готовности устройства\n\n```text\n       Memory\n+--------------------------------------+\n| 0x00 : flags and handler for dev0    |\n| 0x01 : buffer size \u0026 ref for dev0    |\n|   ...                                |\n| 0x1E : flags and handler for dev15   |\n| 0x1F : buffer size \u0026 ref for dev15   |\n|   ...                                |\n| 0x20 : section data : reserved data  |\n|   ...                                |\n| N    : section text : instructions   |\n|   ...                                |\n+--------------------------------------+\n```\n\n### Регистры\n\nПроцессор не имеет регистров общего назначения, так как является стековым, все\nнеобходимые данные для его работы\nхранятся на стеке.\n\nПроцессор имеет следующие специальные регистры:\n\n- `IR` -- регистр ввода (Input Register), размер 32 бита\n\n\u003e Регистр для ручного ввода/вывода данных в/из регистров, предназначен для\n\u003e отладки и тестирования.\n\n- `PC` -- счётчик команд (Program Counter), размер 24 бита\n\n\u003e Содержит адрес текущей выполняемой команды\n\n- `SP` -- указатель на вершину стека (Stack Pointer), размер 24 бита\n\n\u003e Содержит адрес текущей вершины стека\n\n- `CR` -- регистр команды (Command Register), размер 32 бита\n\n\u003e Содержит код команды для последующей дешифровки и исполнения\n\n- `AR` -- регистр адреса (Address Register), размер 24 бита\n\n\u003e Содержит адрес для доступа к памяти, по этому адресу производится чтение и\n\u003e запись данных из памяти\n\n- `DR` -- регистр данных (Data Register), размер 32 бита\n\n\u003e Содержит данные для записи в память или результат чтения из памяти\n\n- `SR` -- регистр состояния (State Register), размер 16 бит\n\n\u003e Содержит флаги состояния процессора (флаг работы, прерывания и т.п.)\n\u003e Старший бит -- флаг работы процессора\n\u003e Бит перед старшим -- флаг прерывания\n\u003e Младшая тетрада -- флаги NZVC (Negative, Zero, Overflow, Carry)\n\u003e Остальные биты -- зарезервированы\n\n- `BR` -- буферный регистр (Buffer Register)\n\n\u003e Используется для промежуточного хранения данных для операций\n\n## Система команд\n\nОсобенности процессора:\n\n- Машинное слова -- 32 бита (4 байта)\n- Доступ к памяти осуществляется через регистры `AR` - указатель на адрес в\n  памяти и `DR` - регистр содержащий данные\n  для записи или результат чтения\n- Устройства ввода-вывода пронумерованы от 0 до 15, работа с устройством\n  происходит через команды `in` и `out` по номеру\n  порта\n- Поток управления:\n  - Инкрементирование счётчика команд\n  - Загрузка команды из памяти в командный регистр\n  - Условный или безусловный переход / Выполнение команды\n  - Если флаг работы в регистре состояния установлен, то продолжить\n  - Проверка на то что прерывания включены, если включены, то проверка на\n    наличие прерывания и уход в обработку\n    прерывания\n  - Перейти к выполнению следующей команды\n\n| Команда                                                            | Стек до исполнения                                                                   | Стек после исполнения                                                              | Описание                                                                                                |\n|--------------------------------------------------------------------|--------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|\n| PUSH                                                               | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e       | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evalue\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e   | Поместить значение на стек                                                                              |\n| POP                                                                | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evalue\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Убрать значение со стека                                                                                |\n| PUSHF                                                              | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e       | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eflags\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e   | Поместить значение регистра состояния на стек                                                           |\n| POPF                                                               | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eflags\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Восстановить значение регистра состояния со стека                                                       |\n| INC \u003cbr\u003e DEC \u003cbr\u003e NEG \u003cbr\u003e NOT \u003cbr\u003e SHL \u003cbr\u003e SHR \u003cbr\u003e ROL \u003cbr\u003e ROR | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evalue\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eres\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Выполнение унарной операции над вершиной стека и помещение результата в стек заместо операнда           |\n| SWAP                                                               | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eb\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e           | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eb\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e         | Поменять местами два верхних элемента на стеке                                                          |\n| DUP                                                                | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e         | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e         | Продублировать значение, находящееся на вершине стека                                                   |\n| NOP                                                                | -                                                                                    | -                                                                                  | Пустая команда                                                                                          |\n| CALL                                                               | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e       | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddress\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e | Перейти в подпрограмму и сохранить адрес возврата на стек                                               |\n| RET                                                                | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddress\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e   | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Возврат из подпрограммы, извлечение адреса с вершины стека и переход по нему                            |\n| HALT                                                               | -                                                                                    | -                                                                                  | Снятие флага работы в регистре состояния                                                                |\n| IRET                                                               | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddress\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eflags\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Возврат из прерывания, извлечение адреса с вершины стека и переход по нему                              |\n| EI                                                                 | -                                                                                    | -                                                                                  | Включить прерывания                                                                                     |\n| DI                                                                 | -                                                                                    | -                                                                                  | Отключить прерывания                                                                                    |\n| ADD \u003cbr\u003e SUB \u003cbr\u003e MUL \u003cbr\u003e DIV \u003cbr\u003e AND \u003cbr\u003e OR \u003cbr\u003e XOR           | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eb\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e           | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eres\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Выполнение бинарной операции над вершиной стека и помещение результата в стек заместо операнда          |\n| ADD \u003cbr\u003e SUB \u003cbr\u003e MUL \u003cbr\u003e DIV \u003cbr\u003e AND \u003cbr\u003e OR \u003cbr\u003e XOR           | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eb\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e           | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eres\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Выполнение бинарной операции над вершиной стека и помещение результата в стек заместо операнда          |\n| LD                                                                 | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddr\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e      | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evalue\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddr\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e  | Прочитать значение ячейки по адресу из вершины стека и добавить его на вершину стека                    |\n| ST                                                                 | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evalue\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddr\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e    | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaddr\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e    | Сохранить значение вершины стека по адресу из второго сверху элемента, убрать верхний элемент со стека  |\n| CMP                                                                | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eb\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e           | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003eres\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eb\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e         | Вычесть второй элемент сверху стека из первого и добавить результат на вершину стека                    |\n| JMP                                                                | -                                                                                    | -                                                                                  | Безусловный переход                                                                                     |\n| JG \u003cbr\u003e JGE \u003cbr\u003e JL \u003cbr\u003e JLE \u003cbr\u003e JE \u003cbr\u003e JZ                       | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evalue\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | \u003ctable\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e...\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e     | Условный переход если верхний элемент со стека удовлетворяет условию, снятие верхнего элемента со стека |\n| BYTE \u003cbr\u003e CHAR \u003cbr\u003e STR                                            | -                                                                                    | -                                                                                  | Псевдокоманды для выделения памяти в секции data                                                        |\n\n### Формат инструкций\n\nФормат адресных и безадресных инструкций различается:\n\n- Адресные:\n  - 6 бит -- Код операции\n  - 2 бита -- Режим адресации\n    - 0b00 -- прямая адресация\n    - 0b01 -- косвенная адресация\n    - 0b10 -- прямая загрузка\n  - 24 бита -- Адрес, сдвиг (24 бит) или значение (16 младших бит)\n- Безадресные:\n  - 8 бит -- Код операции\n  - 24 бит -- Данные для команды\n\nУ безадресных команд старший бит всегда равен нулю, у адресных -- единице.\n\nКоды и формат операций:\n\n### Адресные инструкции\n\n| Код  | Мнемоника | Формат операции                          |\n|------|-----------|------------------------------------------|\n| 0x80 | JMP       | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x84 | JZ        | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x88 | JE        | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x8B | JNZ       | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x90 | JG        | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x94 | JGE       | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x98 | JL        | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x9B | JLE       | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0xA0 | CALL      | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0xA4 | PUSH      | 6 бит код, 2 бита режима, 24 бита адреса |\n\n### Безадресные инструкции\n\n| Код  | Мнемоника | Формат операции                          |\n|------|-----------|------------------------------------------|\n| 0x00 | NOP       | 8 бит код, 24 бита не используются       |\n| 0x02 | POP       | 8 бит код, 24 бита не используются       |\n| 0x03 | PUSHF     | 8 бит код, 24 бита не используются       |\n| 0x04 | POPF      | 8 бит код, 24 бита не используются       |\n| 0x05 | INC       | 8 бит код, 24 бита не используются       |\n| 0x06 | DEC       | 8 бит код, 24 бита не используются       |\n| 0x07 | SWAP      | 8 бит код, 24 бита не используются       |\n| 0x08 | DUP       | 8 бит код, 24 бита не используются       |\n| 0x09 | RET       | 8 бит код, 24 бита не используются       |\n| 0x0A | HALT      | 8 бит код, 24 бита не используются       |\n| 0x0C | IRET      | 8 бит код, 24 бита не используются       |\n| 0x0D | EI        | 8 бит код, 24 бита не используются       |\n| 0x0E | DI        | 8 бит код, 24 бита не используются       |\n| 0x11 | ADD       | 8 бит код, 24 бита не используются       |\n| 0x12 | SUB       | 8 бит код, 24 бита не используются       |\n| 0x13 | MUL       | 8 бит код, 24 бита не используются       |\n| 0x14 | DIV       | 8 бит код, 24 бита не используются       |\n| 0x15 | AND       | 8 бит код, 24 бита не используются       |\n| 0x16 | OR        | 8 бит код, 24 бита не используются       |\n| 0x17 | XOR       | 8 бит код, 24 бита не используются       |\n| 0x18 | NOT       | 8 бит код, 24 бита не используются       |\n| 0x19 | NEG       | 8 бит код, 24 бита не используются       |\n| 0x1A | SHL       | 8 бит код, 24 бита не используются       |\n| 0x1B | SHR       | 8 бит код, 24 бита не используются       |\n| 0x1C | ROL       | 8 бит код, 24 бита не используются       |\n| 0x1D | ROR       | 8 бит код, 24 бита не используются       |\n| 0x1E | CMP       | 8 бит код, 24 бита не используются       |\n| 0x28 | LD        | 6 бит код, 2 бита режима, 24 бита адреса |\n| 0x29 | ST        | 6 бит код, 2 бита режима, 24 бита адреса |\n\n### Пример\n\nДля исходного кода:\n\n```asm\n; Раздел данных, где инициализируется значения\n.section data\nnumber:\n    byte 0x04, 0x00  ; Инициализация числа 1024 (0x0400) в памяти\n\n; Исполнимая секция кода\n.section text\n    ; Загрузка значения из памяти\n    push number\n    ld              ; Загрузить число из метки 'number' на стек\n    push 0x1337     ; Поместить число 0x1337 на стек\n\n    ; Выполнение сложения\n    add             ; Сложить два числа на вершине стека, результат оставить на стеке\n\n    ; Очистка стека\n    pop             ; Удалить результат со стека\n\n    ; Завершение программы\n    halt            ; Остановить выполнение программы\n```\n\nИнструкции представлены в текстовом формате, каждая строчка хранит адрес и\nмашинный код инструкции в 16-разрядном виде (\n`ADDR : OPCODE`):\n\n```text\n000000: 00000400  ; Инициализация переменной number значением 1024\n000004: 91FFFFFB  ; push number с косвенной адресацией, сдвиг 0x4\n000005: 88000000  ; ld\n000006: 01001337  ; push 0x1337\n000007: 11000000  ; add\n000008: 02000000  ; pop\n000009: 0A000000  ; halt\n```\n\n## Транслятор\n\nИнтерфейс командной строки:\n\n```text\nusage: translator.py [-h] -s SOURCE -o OUTPUT\n\nCSA Lab 3 assembly translator\n\noptions:\n  -h, --help            show this help message and exit\n  -s SOURCE, --source SOURCE\n                        File with asm code\n  -o OUTPUT, --output OUTPUT\n                        File with output opcodes\n```\n\n- Пример использования\n  `python translator.py -s examples/sample.asm -o examples/sample.bin`\n  - Обязательные аргументы:\n    - `-s` или `--source` - путь к файлу с исходным кодом\n    - `-o` или `--output` - путь к файлу с бинарным кодом\n  - Необязательные аргументы:\n    - `-h` или `--help` - справка\n\nГлавный модуль программы - [`translator.py`](https://github.com/Armemius/ProcessorEmulator/blob/main/src/translator/translator.py)\n\n### Этапы трансляции\n\n- Лексический анализ\n\n\u003e Разбитие исходного кода на лексические токены\n\n- Синтаксический анализ и построение синтаксического дерева\n\n\u003e Проверка порядка лексем и синтаксических конструкций, построение\n\u003e синтаксического дерева\n\n- Семантический анализ\n\n\u003e Проверка семантики программы, проверка соответствия количества аргументов и\n\u003e типов данных для каждой инструкции\n\n- Генерация кода\n\n\u003e Преобразование синтаксического дерева в машинный код, вычисление адресов\n\u003e меток, упорядочивание секций data и text в\n\u003e памяти\n\n### Правила\n\n- Дублирующиеся метки запрещены\n- В секции `data` можно использовать только псевдокоманды `res`,`byte`, `char` и\n  `str` для выделения и инициализации\n  памяти\n- Программа должна определять точку входа через метку `start` в секции `text`\n\n### Особенности\n\n- Инициализация устройств происходит в начале адресного пространства, до адреса\n  `0x1F`\n- Секция `data` начинается с адреса `0x20`\n- Секция `text` имеет отступ в 16 ячеек памяти от секции `data`\n- Все данные вне зависимости от положения в исходном коде размещаются в секции\n  `data` в порядке объявления до секции\n  `text`\n  в результирующем машинном коде\n- Все определённые метки являются глобальными\n- Обращение к мнемонике инструкции регистронезависимо\n- По умолчанию файл является секцией `text`\n\n## Модель процессора\n\nИнтерфейс командной строки:\n\n```text\nusage: emulator.py [-h] -o SOURCES\n\nCSA Lab 3 emulator\n\noptions:\n  -h, --help            show this help message and exit\n  -o SOURCES, --sources SOURCES\n                        File with operation codes\n  -i INPUT, --input INPUT\n                        File with input data queue\n```\n\n- Пример использования\n  `python emulator.py -o examples/sample.bin`\n  - Обязательные аргументы:\n    - `-o` или `--sources` - путь к файлу с бинарным кодом\n  - Необязательные аргументы:\n    - `-h` или `--help` - справка\n    - `-i` или `--input` - путь к файлу с входными данными для устройств ввода\n    - `-n` или `--interrupt` - использование ввода данных по прерываниям\n\n### Схема `data path`\n\n![Data path](./assets/data_path.png)\n\n### Схема `control unit`\n\n![Control unit](./assets/control_unit.png)\n\n## Тестирование\n\nТестирование выполняется при помощи подхода golden test\n\nПри обновлении файлов в репозитории запускается задание `GitHub Actions`,\nкоторое прогоняет проект через тесты и линтеры:\n\n- задание `test` -- проверка кода через golden test'ы\n- задание `lint-python` -- проверка кода через `flake8`\n- задание `lint-markdown` -- проверка документации через `markdownlint`\n\n### CI при помощи Github Action\n\n```yaml\nname: ProcessorEmulator\n\non:\n  push:\n    branches: [ \"main\", \"dev\" ]\n  pull_request:\n    branches: [ \"main\", \"dev\" ]\n\njobs:\n  lint-markdown:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Set up Node.js\n        uses: actions/setup-node@v3\n        with:\n          node-version: '16'\n\n      - name: Install markdownlint-cli\n        run: |\n          npm install -g markdownlint-cli\n\n      - name: Lint Markdown files\n        run: |\n          markdownlint '**/*.md'\n\n  lint-python:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@v4\n        with:\n          python-version: 3.11\n\n      - name: Install flake8\n        run: |\n          python -m pip install --upgrade pip\n          pip install flake8\n\n      - name: Lint Python files\n        run: |\n          flake8 .\n\n  test:\n    runs-on: ubuntu-latest\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v4\n\n      - name: Set up Python\n        uses: actions/setup-python@v4\n        with:\n          python-version: 3.11\n\n      - name: Install dependencies\n        run: |\n          python -m pip install --upgrade pip\n          pip install pytest\n          pip install pytest-timeout\n\n      - name: Test\n        run: |\n          pytest\n```\n\n### Результаты тестирования\n\nТестирование осуществляется при помощи утилиты `pytest` и `pytest-timeout`,\nрезультаты выполнения теста:\n\n```text\n(.venv) PS C:\\Users\\armemius\\Documents\\projects\\csa-lab-3\u003e pytest\n======================================================================================================= test session starts =======================================================================================================\nplatform win32 -- Python 3.10.11, pytest-8.3.3, pluggy-1.5.0\nrootdir: C:\\Users\\armemius\\Documents\\projects\\csa-lab-3\nplugins: timeout-2.3.1\ncollected 4 items                                                                                                                                                                                                                  \n\ntest\\golden_test.py ....                                                                                                                                                                                                     [100%]\n\n======================================================================================================== 4 passed in 1.92s ======================================================================================================== \n```\n\n### Программы, используемые для тестирования\n\n#### Hello World\n\n```nasm\n.section devices\ndev0:\n        byte 0x81\n        addr null\n        byte 0x10\n        addr buffer_0\ndev1:\n        byte 0x81\n        addr null\n        byte 0x10\n        addr buffer_0\n\n.section data\nbuffer_0:\n        str \"Hello, World!\"\n        byte 0x0\n\n.section text\nstart:\n    halt\n```\n\nВывод программы:\n\n```text\n\u003e Hello, World!\n```\n\nЖурнал работы:\n\n```text\nTick: 37 | Instruction: 1   | PC: 000034 | SP: 000000 | CR: F0000002 | AR: 000002 | DR: 81000000 | SR: 8008 | BR: 00000002 | TOS: 81000000 | NOS: 10000020\nTick: 42 | Instruction: 2   | PC: 000035 | SP: 000000 | CR: 0A000000 | AR: 000034 | DR: 0A000000 | SR: 0008 | BR: 00000034 | TOS: 81000000 | NOS: 10000020\n\n```\n\n#### Cat\n\n```nasm\n.section devices\ndev0:\n        byte 0x81\n        addr null\n        byte 0xFF\n        addr buffer_0\ndev1:\n        byte 0x01\n        addr null\n        byte 0xFF\n        addr buffer_0\n\n.section data\nbuffer_0:\n        res 0xFF\n\n.section text\nstart:\n    unset dev0\n    check dev0\n    jz end\n    set dev1\n    jmp start\n\nend:\n    halt\n```\n\nВывод программы:\n\n```text\n\u003c Hello, World!\n\u003e Hello, World!\n\u003c I\n\u003e I\n\u003c love\n\u003e love\n\u003c computer\n\u003e computer\n\u003c science\n\u003e science\n```\n\nЖурнал работы:\n  \n```text\nTick: 40  | Instruction: 1    | PC: 000071 | SP: 000000 | CR: F4000000 | AR: 000000 | DR: 01000000 | SR: 8000 | BR: 00000000 | TOS: 81000000 | NOS: FF000020\nTick: 70  | Instruction: 2    | PC: 000072 | SP: 000000 | CR: FC000000 | AR: FFFFFE | DR: 80000000 | SR: 8008 | BR: 80000000 | TOS: 81000000 | NOS: FF000020\nTick: 74  | Instruction: 3    | PC: 000073 | SP: 000000 | CR: 84000075 | AR: 000072 | DR: 84000075 | SR: 8008 | BR: 00000072 | TOS: 81000000 | NOS: FF000020\nTick: 111 | Instruction: 4    | PC: 000074 | SP: 000000 | CR: F0000002 | AR: 000002 | DR: 81000000 | SR: 8008 | BR: 00000002 | TOS: 81000000 | NOS: FF000020\nTick: 116 | Instruction: 5    | PC: 000070 | SP: 000000 | CR: 80000070 | AR: 000074 | DR: 80000070 | SR: 8008 | BR: 00000074 | TOS: 81000000 | NOS: FF000020\nTick: 156 | Instruction: 6    | PC: 000071 | SP: 000000 | CR: F4000000 | AR: 000000 | DR: 01000000 | SR: 8000 | BR: 00000000 | TOS: 81000000 | NOS: FF000020\nTick: 186 | Instruction: 7    | PC: 000072 | SP: 000000 | CR: FC000000 | AR: FFFFFE | DR: 80000000 | SR: 8008 | BR: 80000000 | TOS: 81000000 | NOS: FF000020\nTick: 190 | Instruction: 8    | PC: 000073 | SP: 000000 | CR: 84000075 | AR: 000072 | DR: 84000075 | SR: 8008 | BR: 00000072 | TOS: 81000000 | NOS: FF000020\nTick: 227 | Instruction: 9    | PC: 000074 | SP: 000000 | CR: F0000002 | AR: 000002 | DR: 81000000 | SR: 8008 | BR: 00000002 | TOS: 81000000 | NOS: FF000020\nTick: 232 | Instruction: 10   | PC: 000070 | SP: 000000 | CR: 80000070 | AR: 000074 | DR: 80000070 | SR: 8008 | BR: 00000074 | TOS: 81000000 | NOS: FF000020\nTick: 272 | Instruction: 11   | PC: 000071 | SP: 000000 | CR: F4000000 | AR: 000000 | DR: 01000000 | SR: 8000 | BR: 00000000 | TOS: 81000000 | NOS: FF000020\nTick: 302 | Instruction: 12   | PC: 000072 | SP: 000000 | CR: FC000000 | AR: FFFFFE | DR: 80000000 | SR: 8008 | BR: 80000000 | TOS: 81000000 | NOS: FF000020\nTick: 306 | Instruction: 13   | PC: 000073 | SP: 000000 | CR: 84000075 | AR: 000072 | DR: 84000075 | SR: 8008 | BR: 00000072 | TOS: 81000000 | NOS: FF000020\nTick: 343 | Instruction: 14   | PC: 000074 | SP: 000000 | CR: F0000002 | AR: 000002 | DR: 81000000 | SR: 8008 | BR: 00000002 | TOS: 81000000 | NOS: FF000020\nTick: 348 | Instruction: 15   | PC: 000070 | SP: 000000 | CR: 80000070 | AR: 000074 | DR: 80000070 | SR: 8008 | BR: 00000074 | TOS: 81000000 | NOS: FF000020\nTick: 388 | Instruction: 16   | PC: 000071 | SP: 000000 | CR: F4000000 | AR: 000000 | DR: 01000000 | SR: 8000 | BR: 00000000 | TOS: 81000000 | NOS: FF000020\nTick: 418 | Instruction: 17   | PC: 000072 | SP: 000000 | CR: FC000000 | AR: FFFFFE | DR: 80000000 | SR: 8008 | BR: 80000000 | TOS: 81000000 | NOS: FF000020\nTick: 422 | Instruction: 18   | PC: 000073 | SP: 000000 | CR: 84000075 | AR: 000072 | DR: 84000075 | SR: 8008 | BR: 00000072 | TOS: 81000000 | NOS: FF000020\nTick: 459 | Instruction: 19   | PC: 000074 | SP: 000000 | CR: F0000002 | AR: 000002 | DR: 81000000 | SR: 8008 | BR: 00000002 | TOS: 81000000 | NOS: FF000020\nTick: 464 | Instruction: 20   | PC: 000070 | SP: 000000 | CR: 80000070 | AR: 000074 | DR: 80000070 | SR: 8008 | BR: 00000074 | TOS: 81000000 | NOS: FF000020\nTick: 504 | Instruction: 21   | PC: 000071 | SP: 000000 | CR: F4000000 | AR: 000000 | DR: 01000000 | SR: 8000 | BR: 00000000 | TOS: 81000000 | NOS: FF000020\nTick: 534 | Instruction: 22   | PC: 000072 | SP: 000000 | CR: FC000000 | AR: FFFFFE | DR: 80000000 | SR: 8008 | BR: 80000000 | TOS: 81000000 | NOS: FF000020\nTick: 538 | Instruction: 23   | PC: 000073 | SP: 000000 | CR: 84000075 | AR: 000072 | DR: 84000075 | SR: 8008 | BR: 00000072 | TOS: 81000000 | NOS: FF000020\nTick: 575 | Instruction: 24   | PC: 000074 | SP: 000000 | CR: F0000002 | AR: 000002 | DR: 81000000 | SR: 8008 | BR: 00000002 | TOS: 81000000 | NOS: FF000020\nTick: 580 | Instruction: 25   | PC: 000070 | SP: 000000 | CR: 80000070 | AR: 000074 | DR: 80000070 | SR: 8008 | BR: 00000074 | TOS: 81000000 | NOS: FF000020\nTick: 620 | Instruction: 26   | PC: 000071 | SP: 000000 | CR: F4000000 | AR: 000000 | DR: 01000000 | SR: 8000 | BR: 00000000 | TOS: 01000000 | NOS: FF000020\nTick: 650 | Instruction: 27   | PC: 000072 | SP: 000000 | CR: FC000000 | AR: FFFFFE | DR: 00000000 | SR: 8004 | BR: 80000000 | TOS: 01000000 | NOS: FF000020\nTick: 655 | Instruction: 28   | PC: 000075 | SP: 000000 | CR: 84000075 | AR: 000072 | DR: 84000075 | SR: 8004 | BR: 00000072 | TOS: 01000000 | NOS: FF000020\nTick: 660 | Instruction: 29   | PC: 000076 | SP: 000000 | CR: 0A000000 | AR: 000075 | DR: 0A000000 | SR: 0004 | BR: 00000075 | TOS: 01000000 | NOS: FF000020\n```\n\n## Статистика по алгоритмам\n\n```text\n| алг            | LoC | code инстр. | инстр.  | такт.  |\n| hello_world    | 21  | 2           | 2       | 41     |\n| hello_username | 267 | 197         | 2421    | 22034  |\n| cat            | 27  | 6           | 29      | 660    |\n| prob5          | 228 | 146         | 7440    | 68469  |\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmemius%2Fprocessoremulator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farmemius%2Fprocessoremulator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farmemius%2Fprocessoremulator/lists"}