Files
obsidian/Computer Science/Архитектуры/Платформа Wrench.md
T
roma-dxunvrs 181e2528b6 15.09.26
2026-09-15 20:28:25 +03:00

6.9 KiB
Raw Blame History

  • Учебная платформа и симулятор для курса архитектуры компьтера
  • Разработана для практического изучения 5 принципиально разных архитектурных парадигм в рамках единого инструментария
  • Сайт
  • Исходники

Файлы конфигов

Каждый тест программы описывается декларативным .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 например