Машина: RISC5

RISC5 — процессор, который Вирт спроектировал для Project Oberon, когда решил, что коммерческие процессоры стали слишком сложными, чтобы объяснить их студентам. Описание занимает около сорока страниц, реализация — примерно двести строк Verilog.

Регистры

Шестнадцать регистров по 32 бита: R0…R15. Все равноправны на уровне железа; разделение труда — соглашение компилятора, и оно записано прямо в ORG.Mod:

регистр роль
R0…R11 вычисления, параметры, временные значения
R12 (MT) таблица модулей; через неё же уходят ловушки
R13 (SB) статическая база: начало данных текущего модуля
R14 (SP) вершина стека
R15 (LNK) адрес возврата из процедуры

Плюс четыре флага — N (знак), Z (ноль), C (перенос), V (переполнение) — и отдельный регистр H, куда попадает старшее слово произведения и остаток от деления.

Счётчик команд адресует слова, а не байты, и он двадцатидвухбитный. Значит адресное пространство — четыре миллиона слов, шестнадцать мегабайт; реальной памяти в системе один мегабайт.

Четыре формата команд

Вся система команд укладывается в четыре формата, различаемых двумя старшими битами.

F0  00uv | a | b | op |  (не исп.)  | c      регистр-регистр
F1  01uv | a | b | op |      im (16)         регистр-непосредственное
F2  10uv | a | b |        off (20)           чтение и запись памяти
F3  11uv | cond  |        off (24)           переход

Поля: a — приёмник, b и c — операнды, op — код операции, u и v — модификаторы. Операций ровно шестнадцать:

MOV LSL ASR ROR   AND ANN IOR XOR   ADD SUB MUL DIV   FAD FSB FML FDV

ANN — это «и-не»: b AND NOT c. Умножение и деление занимают десятки тактов и на это время останавливают конвейер. Четыре последние — арифметика с плавающей точкой, одинарной точности, прямо в железе.

Биты u и v уточняют операцию там, где это нужно:

Для большинства операций u и v не читаются вовсе. Это не догадка: мы проверили исполнением — запустили каждую форму рядом с базовой на одних операндах и сложили результаты по модулю два. Из тридцати двух сравнений двадцать семь дали ноль.

Переходы

Формат F3 задаёт условие четырьмя битами. Старший бит инвертирует, младшие три выбирают проверяемую величину:

код условие код условие
0 MI знак 8 PL
1 EQ ноль 9 NE
2 CS перенос 10 CC
3 VS переполнение 11 VC
4 LS ниже или равно 12 HI
5 LT меньше 13 GE
6 LE меньше или равно 14 GT
7 всегда 15 никогда

Переход бывает по смещению и по регистру, со связью и без. «Со связью» значит, что адрес следующей команды кладётся в R15 — так делается вызов процедуры.

Ловушки

Отдельной команды прерывания в RISC5 нет. Ловушка — это переход по регистру MT со связью, а в неиспользуемые биты команды компилятор кладёт полезный груз: в разряды 23–8 позицию в исходном тексте, в разряды 7–4 номер ошибки. Железо эти биты не читает вовсе; их достаёт обработчик — прямо из команды, на которой споткнулся.

Поэтому сообщение об ошибке выглядит так:

pos 6734  TRAP  4 in ORB at 0001EC10

Номер 4 означает разыменование NIL. Номер 1 — выход за границу массива: именно эту проверку кодогенератор вставляет перед каждым индексированием.

Память и устройства

Карта простая:

диапазон что
000000…0FFFFF ОЗУ, один мегабайт
0E7F00…0FFFFF кадровый буфер, 1024×768 точек по одному биту
FFE000…FFFFBF ПЗУ с загрузчиком
FFFFC0…FFFFFF регистры устройств

Устройств немного: таймер, светодиоды, последовательный порт, SPI для SD-карты, мышь и клавиатура. Мышь читается одним словом: координаты в младших двух полях по двенадцать бит, кнопки в разрядах 24–26, готовность клавиатуры — разряд 28.

Кадровый буфер устроен непривычно: строки хранятся снизу вверх. Первое слово буфера — это нижняя строка экрана. Наивная выкладка даёт перевёрнутую картинку, и на этом спотыкаются все, кто пишет для этой машины впервые.

Чего в машине нет

Нет блока управления памятью, нет колец защиты, нет разделения на режим ядра и режим пользователя. Любая команда может записать любое слово памяти. Нет кэша, нет предсказания переходов, нет внеочередного исполнения — время исполнения команды считается по таблице и всегда одно и то же.

Это не упущение, а позиция: машина должна помещаться в голову целиком. Чем это оборачивается на практике, вы увидите в лабораторной №4.