68 lines
6.9 KiB
Markdown
68 lines
6.9 KiB
Markdown
- Учебная платформа и симулятор для курса архитектуры компьтера
|
||
- Разработана для практического изучения 5 принципиально разных архитектурных парадигм в рамках единого инструментария
|
||
- [Сайт](https://wrench.edu.swampbuds.me)
|
||
- [Исходники](https://github.com/ryukzak/wrench)
|
||
## Файлы конфигов
|
||
Каждый тест программы описывается декларативным `.yaml` файлом
|
||
- `limit` - максимальное число инструкций (защита от зацикливаний)
|
||
- `memory_size` - размер адресного пространства (по умолчанию 8 Кб)
|
||
- `memory_mapped_io` - начальное состояние портов
|
||
- `0x80` - входной поток
|
||
- `0x84` - выходной поток
|
||
- `reports` - секция для вывода в логи
|
||
### slice
|
||
Определяет какую часть журнала симуляции выводить
|
||
- `slice: all` - состояние процессора на каждом шаге
|
||
- `slice: last` - только финальное состояние на момент завершения
|
||
### Доступные метрики
|
||
Указываются в секции `view` в `reports`
|
||
- `{sim:instruction-count}` - число выполненных инструкций
|
||
- `{layout:sections-size}` - декларированный размер секций `.text` и `.data`
|
||
- `{mem:*-ranges}` - дипазоны адресов памяти, к которым реально обращался процессор
|
||
- `{memory:table}` - полная карта памяти с процентом покрытия
|
||
### Блок проверки
|
||
- Блок `assert` в секции `reports` отвечает за автоматическую проверку результата работы программы
|
||
- `[Состояние до запуска] >>> [Ожидаемое состояние после остановки]`
|
||
- Например, `numio[0x80]: [72, 101, 10] >>> []` (до запуска лежали три байта, после работы должен стать пустым)
|
||
- Или, `symio[0x84]: "" >>> "HELLO"`
|
||
- Что можно проверять
|
||
- Потоки ввода-вывода (числовое представление `numio` или строковое представление `symio` в ASCII) Непечатные символы (ASCII код меньше 32) заменяются на знаки вопроса `?`
|
||
- Состояние памяти (`mem[0..31]: 05 48 45 ...`)
|
||
- Регистры и счетчики процессора
|
||
## Стандарт ввода-вывода MMIO
|
||
Во всех архитектурах чтение/запись внешних устройств настроены абсолютно одинаково
|
||
- Адрес `0x80` - входной поток - очередь FIFO. При чтении процессором выдает очередной элемент из тестового массива
|
||
- Адрес `0x84` - выходной поток. Принимает 32-битные слова. Запись любого числа отправляет его в выходной поток
|
||
## Порядок байтов и адресация
|
||
Адресация побайтовая, то есть один адрес - один байт. Например, в 32-битной архитектуре чтение по `0x80` захватывает сразу `0x80, 0x81, 0x82, 0x83`. Порядок - `Little Endian`
|
||
## Крайние случаи
|
||
### Запись во входной порт (0x80)
|
||
- `load_imm 42` $\to$ `store_addr 0x80`
|
||
- Программа не упала, продолжила работу. Данные исчезли навсегда
|
||
- Контроллер порта `0x80` работает только на чтение
|
||
### Чтение из выходного порта (0x84)
|
||
- Попытались сделать `load_addr 0x84` (или `load_acc` по этому адресу)
|
||
- Аварийное завершение `ERROR: input is depleted` по адресу `132` (`0x84`)
|
||
- Порт `0x84` — это write-only устройство. У него нет входящей очереди (FIFO), из которой процессор мог бы прочитать байт
|
||
### Исполнение кода из порта ввода (JMP 0x80)
|
||
- jmp 0x80`
|
||
- Аварийное завершение `ERROR: instruction in memory corrupted`
|
||
- `PC` выставил адрес `0x80`. Процессор забрал из очереди ввода пользовательский байт (например, букву `'H'` = 72) и попытался декодировать его как машинную команду (Opcode). Команды с таким кодом нет
|
||
### Размещение данных прямо в портах (`.org 0x80`)
|
||
- Написали `.org 0x80`, положили `.word 42`, а следом секцию `.text` с командой `halt`
|
||
- Аварийное завершение при старте: `ERROR: iomemory[132]: instruction corrupted`
|
||
- Данные `.word 42` (4 байта) заняли адреса `0x80, 0x81, 0x82, 0x83`.
|
||
- Код программы (`halt`) "перелился" в следующую свободную ячейку — `0x84` (132)
|
||
- Процессор попытался стартовать с адреса `0x84` (считая его началом `.text`)
|
||
- Но `0x84` - это порт только для записи! Процессор не смог прочитать оттуда код и умер при старте
|
||
### Несколько `.org`
|
||
- Ошибка компилятора `multiple .org directives not allowed`
|
||
- В одной секции - один `.org` (один в `.text`, один в `.data`)
|
||
### Чтение из пустого ввода
|
||
- `ERROR: memory access error: input is depleted`
|
||
### Сдвиги
|
||
- Если сдвинуть числа больше чем на 32, то просто зануление - для сдвига влево
|
||
- Для сдвигов вправо, если исходное число было положительным - зануление
|
||
- Для сдвигов вправо, если иходное число было отрицательным - `-1`
|
||
### Переходы
|
||
- В отличие от БЭВМ переходы тут работают иначе. Переходы, которые сравнивают с нулем, учитывают только знак (в бэвм учитывали еще `n+v(mod2)`). Поэтому надо самому реализовывать переходы, которые учитывают специфику доп. кода через `bvz+bltz` например |