Подготовка к лаб.6. Микропрограммирование
Скачайте набор микропрограммиста на архитектуре Mic-1. Распакуйте архив в домашний каталог, откройте в терминале распакованный каталог Mic1MMV. Запустите графический симулятор Mic-1 командой:
$ java -jar Mic1MMV.jar
Данный симулятор предназначен для интерпретации инструкций IJVM на микроархитектуре Mic-1. Задача лабораторной работы состоит в расширении набора инструкций IJVM и реализации новых инструкций на микропрограммном уровне с помощью микроассемблера MAL. Схема работы может быть представлена графически — посмотрите на неё. Упомянутые программы (IJVM-ассемблер и MAL) спрятаны внутри данного графического симулятора.
Для работы данного симулятора должна быть установлена виртуальная машина Java.
Для решения каждой задачи нужно выполнить одну и ту же последовательность действий:
Скачать .jas-файл с программой (будет дан в задаче) на ассемблере IJVM, где используется новая инструкция IJVM, которую нужно реализовать в данной задаче. Имеет смысл заглянуть внутрь файла.
Добавить в описание ассемблера IJVM (файл ijvm-mmcs.conf из архива) имя новой инструкций и её код (вообще говоря, произвольный новый, но в задаче он будет указан).
Добавить в микропрограмму (файл mic1mmv-mmcs.mal из архива) последовательность микрокоманд, реализующих новую инструкцию.
Перезапустить симулятор из консоли (это заставит его прочитать обновления в .conf-файле для IJVM). Сассемблировать и загрузить файл с модифицированной микропрограммой (mic1mmv-mmcs.mal, команда меню симулятора File → Assemble / Load MAL file), сассемблировать и загрузить файл с программой, скаченной на первом шаге (команда меню симулятора File → Assemble / Load JAS file).
Запустить симуляцию (см. ниже).
У симулятора есть несколько режимов («скоростей» — найдите слово Speed в окне симулятора) работы, от выбора скорости зависит то, какое количество действий выполняется за одно нажатие синей стрелочки вправо:
- SubClock — по фазе («подциклу») одного цикла (запуск шины B, запуск АЛУ, запуск шины C и запись в регистры — три вида подциклов внутри одного цикла);
- Clock — по одной микрокоманде (одному «циклу»);
- IJVM — по одной инструкции процессора;
- Prog — непрерывно (до конца программы или до очередной операции ввода с клавиатуры).
К большому сожалению переключение между скоростями не доступно по ходу выполнения программы. Поэтому разумный алгоритм проверки правильности решения на данном симуляторе выглядит так:
Первый запуск программы проводить на скорости Prog. Результат в выданных .jas-программах всегда будет помещаться на стек и в конце выполнения программы будет видно, правильное там оказалось значение или нет (вершина стека выделена красным в поле Stack Area). Если оно правильное, то можно решать следующую задачу.
Если значение на стеке неправильное, то нужно переключиться на скорость Clock (или даже SubClock) и выполнять программу по шагам, наблюдая за тем, какие выполняются микрокоманды (видно в поле под переключателем скоростей) и как изменяются значения регистров. Это позволит найти ошибку в вашей микропрограмме, хотя понадобится много нажатий на синюю стрелочку вправо.
В начале работы программы выполняются три стандартных цикла (
Main1 | nop1 | Main1
), которые позволяют подхватить из памяти первую инструкцию этой программы — не пугайтесь и пропускайте их.
Задачи
Скачайте программу, использующую новую инструкцию DEC [предлагаемый код: 0x16], которая уменьшает слово на вершине стека на единицу. Выполните необходимые действия для микропрограммной реализации этой инструкции (см. первый список на этой странице сверху).
Идеи. Действуйте по аналогии с тем, что уже есть в .conf и .mal-файлах.- В .conf-файл добавляется имя новой инструкции (DEC) и её код.
- В .mal-файле нужно не забыть вставить директиву .label, которая жёстко задаёт адрес микрокоманды с заданной меткой. Это делается для выполнения условия: адрес первой микрокоманды для выполнения инструкции X должен совпадать с бинарным кодом X.
- Алгоритм для микропрограммы: уменьшить содержимое TOS на 1 и результат записать в TOS и в MDR (в MDR — для будущего «сброса» в память: вершина стека хранится в двух местах, в TOS и в памяти по адресу SP). Загрузить в MAR значение SP и вызвать команду wr, чтобы записать новое значение вершины стека в память. В этом же месте сделать goto Main1 (делается в конце каждого отрезка микрокоманд для каждой инструкции — это можно видеть в файле).
Скачайте программу, использующую новую инструкцию IADD3 [предлагаемый код: 0x20], которая берёт со стека три числа и кладёт на стек их сумму. Выполните необходимые действия для микропрограммной реализации этой инструкции.
Идеи. Действуйте по аналогии с реализацией стандартной инструкции IJVM по имени IADD.- Имя метки первой микрокоманды удобно выбрать таким: iadd31. Последующие инструкции отмечать iadd32, iadd33 и т. д. (повторим: см. реализацию IADD, которая выполнена командами iadd1, iadd2, iadd3, свою реализацию разместите под iadd3 через пустую строку).
- Поскольку требуется три числа со стека, одно из которых (вершина) уже есть в регистре TOS, то потребуется два чтения из памяти (rd).
- Решение этой задачи может уложиться в пять микрокоманд (возможно, есть и более короткое решение) без пустых циклов ожидания данных из памяти. Для этого нужно вспомнить, что чтение из памяти (команда rd) занимает ровно один цикл. Это, в частности, значит что на следующем после вызова rd цикле ещё можно использовать старое значение MDR — эта хитрая идея позволяет уложится в пять циклов. Если она не ясна, скорее всего придётся вставлять дополнительные пустые циклы для ожидания подгрузки данных из памяти (пустой цикл вставляется так: пишется метка, например, iadd32, а затем переход на новую строку и следующий цикл, уже непустой).
Скачайте программу, использующую новую инструкцию IDEC, которая уменьшает значение переменной (первый агрумент) на значение константы (второй аргумент), в предположении, что оба аргумента - неотрицательные числа. Выберите для новой инструкции любой свободный код. Выполните необходимые действия для микропрограммной реализации этой инструкции.
Добавьте в набор инструкций IJVM инструкцию BUMUL с одним однобайтовым аргументом, эта инструкция должна снимать со стека слово, и класть на стек произведение этого слова и своего аргумента. Составьте jas-программу, которая использует эту инструкцию — например, кладёт на стек 3, а потом вызывает BUMUL 2. Идеи для микропрограммной реализации стоит брать из реализации UMUL и реализации любой инструкции с однобайтовым параметром, например, BIPUSH.
Идеи. Умножение реализуется через многократное сложение.
- Будет несколько инструкций типа goto label.
- Для организации цикла на микропрограммном уровне следует использовать goto, условие остановки реализуется с помощью микрокоманды:
Z = регистр; if (Z) goto метка_выхода_из_цикла; else goto метка_начала_цикла
- 7 октября 2022, 20:16