Компьютерная архитектура iiixmish2
Введение
правитьОпределения
править- Регистр процессора
- Регистр процессора — это поле определённой длины, которое находится в памяти процессора. Доступ к регистру очень быстр, его содержимое можно сохранить в память и обратно. Бывает как доступен из программы, так и нет.
- Язык ассемблера
- Язык ассемблера — это низкоуровневый язык программирования, максимально приближённый к командам самого процессора.
- Ассемблерная директива
- Ассемблерная директива («псевдокоманда») — это команда ассемблера. Директивы влияют на компиляцию программы. Примеры в Makexm2c —
.skip
,.ascii
и.def
.
Учебник
правитьДанный учебник учит программированию на Makexm2c.
Makexm2c
правитьMakexm2c — это язык ассемблера, предназначенный для создания программ под iiixmish2. Бо́льшая часть команд Makexm2c представляет собой мнемонические обозначения инструкций iiixmish2. Важно упомянуть, что в большинстве инструкций типы параметров определены. Например, для add
применимы только регистры; для mov
— регистр и константа.
iiixmish2
правитьIiixmish2 — это 32-разрядная компьютерная архитектура. Она имеет >=10 миллионов ячеек памяти, 44 пользовательских регистров, 2000 ячеек видеопамяти, более 30 команд и экран 63x30 символов.[1]
Ниже представлены названия iiixmish2-инструкций и соответствующие signed char
-опкоды[2]:
Название | Код операции |
---|---|
ADD |
-2 |
SUB |
-3 |
MOV |
-4 |
ILD |
-5 |
VLD |
-6 |
LD |
-7 |
ISV |
-8 |
VSV |
-9 |
IFA |
-11 |
IFB |
-12 |
IFC |
-13 |
IFD |
-14 |
UPDD |
-15 |
OFF |
-16 |
VRST |
-17 |
JMP |
-18 |
MUL |
-21 |
DIV |
-22 |
INC |
-26 |
DEC |
-27 |
TNP |
-28 |
MOD |
-29 |
LSHIFT |
-38 |
RSHIFT |
-39 |
XOR , OR , AND |
-40, -41, -42 |
TIME |
-43 |
TRST |
-44 |
RISV |
-45 |
RVSV |
-46 |
RILD |
-47 |
RVLD |
-48 |
Получение необходимого
правитьСкачайте свободную реализацию iiixmish2 здесь, а также ассемблер здесь. Раньше мы предлагали читателям загрузить makexm2c-tools, но сейчас он устарел. Ассемблер, входящий в старый комплект, был заменён новым и быстрым mxm2c-as.
Распакуйте полученные архивы. Скомпилируйте программы, используя OpenJDK 17 и GCC. В Debian, Вы можете установить его, выполнив следующую команду:
$ sudo apt install openjdk-17-jdk
Выполните java --version
.
Синтаксис
правитьMakexm2c-программы могут состоять из команд:
<название> [<аргумент 0>[[,] <аргумент 1>]…]
, псевдокоманд (директив):
.<название> [<аргумент 0>[ <аргумент 1>]]
, меток:
<название>:
и комментариев.
К регистрам можно подставлять «UR» (UR0, UR1…).
Теперь мы можем написать первую программу. Она будет выводить на экран компьютера «hello, world».
Создайте файл «hello.s» и вставьте в него следующее:
mov UR0, <main>
jmp UR0
;;;;; данные ;;;;;
str:
.skip 12
.ascii <str> "hello, world"
.byte 0
;;;;;;;;;;;;;;;;;;;;
main:
mov UR0, <str>
mov UR6, 0
loop:
ild UR0, UR8
mov UR10, 0
mov UR11, <final>
if UR8 == UR10, UR11
vsv UR8, UR6
inc UR0
inc UR6
mov UR11, <loop>
jmp UR11
final:
updd
Это код на Makexm2c, переведите его в код, понятный iiixmish2, используя ассемблер:
$ mxm2c-as hello.s hello
Отлично! Запустите виртуальную машину, передав полученный файл:
$ java downadow.iiixmish2.main.Iiixmish2 hello
Данная программа записывает строку str в видеопамять до тех пор, пока не встретится нулевой байт, после чего переходит к final и обновляет экран. Конец программы.
Регистры
правитьКак уже было сказано ранее, iiixmish2 имеет 44 пользовательских регистров (п. реги́стры).
Избегайте использования п. регистров 2, 3, 4 и 5, т. к. они могут использоваться некоторыми командами.[2]
Присваивание
правитьКоманда mov
сохраняет число в п. регистр, число не должно превышать один байт. Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
АДРЕС п. регистра, который должен принять ЧИСЛО |
ЧИСЛО |
ЧИСЛО для сохранения |
Пример использования:
mov UR10, 64
Также можно вставлять 'СИМВОЛ'
вместо числа, пример:
mov UR10, 'j'
то же, что и
mov UR10, 106
Сложение
правитьКоманда add
складывает два п. регистра, сохраняет результат в п. регистр. Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра, содержащего первое слагаемое |
ЧИСЛО |
адрес п. регистра, содержащего второе слагаемое |
ЧИСЛО |
адрес п. регистра, в который следует поместить сумму |
Пример использования:
add UR0 UR6, UR9
Запятые между аргументами и «UR» к адресам, — необязательны.
Вычитание
правитьКоманда sub
вычитает из п. регистра значение другого п. регистра, результат сохраняется в п. регистр.
Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра, содержащего уменьшаемое |
ЧИСЛО |
адрес п. регистра, содержащего вычитаемое |
ЧИСЛО |
адрес п. регистра, в который следует поместить разность |
Пример использования:
sub UR6 UR8, UR0
Загрузка
правитьКоманда ld
загружает значение п. регистра в другой п. регистр.
Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра, который следует загрузить в ДРУГОЙ п. регистр |
ЧИСЛО |
адрес ДРУГОГО п. регистра |
Пример использования:
ld UR1, UR0
Умножение
правитьКоманда mul
умножает п. регистр на другой п. регистр, результат сохраняется в п. регистр.
Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра, содержащего множимое |
ЧИСЛО |
адрес п. регистра, содержащего множитель |
ЧИСЛО |
адрес п. регистра, в который следует поместить произведение |
Пример использования:
mul UR6 UR8, UR0
Деление
правитьКоманда div
делит п. регистр на другой п. регистр, результат сохраняется в п. регистр.
Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра, содержащего делимое |
ЧИСЛО |
адрес п. регистра, содержащего делитель |
ЧИСЛО |
адрес п. регистра, в который следует поместить частное |
Пример использования:
div UR6 UR8, UR0
Получение остатка от деления
правитьКоманда mod
делит п. регистр на другой п. регистр, остаток сохраняется в п. регистр.
Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра, содержащего делимое |
ЧИСЛО |
адрес п. регистра, содержащего делитель |
ЧИСЛО |
адрес п. регистра, в который следует поместить остаток |
Пример использования:
mod UR0 UR29, UR8
Команда inc
увеличивает п. регистр на единицу. Пример использования:
inc UR0
Команда dec
уменьшает п. регистр на единицу. Пример использования:
dec UR0
Изменение знака
правитьКоманда tnp
изменяет знак п. регистра, пример использования:
tnp UR14
mov2
правитьmov2
— синоним mov
. Не используйте его в новом коде.
Сдвиг
правитьСледующий код выполняет операцию вида UR20 << UR19 (сдвиг битов влево) и сохраняет результат в UR8:
lshift UR20 UR19, UR8
UR8 = UR20 >> UR19
:
rshift UR20 UR19, UR8
Для побитовых XOR, OR и AND, используйте одноимённые инструкции.
Получение времени
правитьКоманда time
копирует в заданный регистр кол-во миллисекунд, приблизительно начиная от запуска процессора. Принимает один аргумент. trst
сбрасывает время.
Комментарии
правитьКоммента́рий — это текст в коде программы, который не влияют на её работу, но, как правило, помогает лучше понять её. В Makexm2c комментарии могут быть разных видов.[3]
Ме́тки — в Makexm2c — это неотъемлемая часть языка. Обращение к метке вставляет на месте обращения адрес, по которому располагается эта метка в двоичной форме программы. Пример:
метка:
nop
nop
mov UR0, <метка>
Для обращения, название метки, заключённое в <
и >
, вставляется в нужное место в программе.
Для создания именованных констант используется директива .def
, пример:
.def %CONST% "0"
создаст именованную константу «CONST» со значением «0».
Обращение к именованным константам отличается от обращения к меткам лишь тем, что название заключается в %
, а не <
и >
.
Задание
Потренируйтесь с пройденными командами.
В iiixmish2 есть команды для создания условных переходов. Рассмотрим, как использовать их в Makexm2c.
Равно
правитьВ iiixmish2 нет инструкций вроде BRz, BRn и т. д., ветвление реализуется посредством команд IFA, IFB, IFC и IFD. Для создания перехода вроде «если значение п. регистра А равно значению регистра Б, то выполнить переход на <значение п. регистра В>», воспользуйтесь следующей конструкцией:
if АДРЕС0 == АДРЕС1, АДРЕС2
Название | Описание |
---|---|
АДРЕС0 |
адрес первого п. регистра для сравнения |
АДРЕС1 |
адрес второго п. регистра для сравнения |
АДРЕС2 |
адрес п. регистра, на значение которого нужно перейти |
Ясно? Идём дальше.
Неравно
правитьif АДРЕС0 != АДРЕС1, АДРЕС2
Больше
правитьif АДРЕС0 > АДРЕС1, АДРЕС2
Меньше
правитьif АДРЕС0 < АДРЕС1, АДРЕС2
Видеопамять
правитьКак уже говорилось во введении, iiixmish2 имеет 2000 ячеек видеопамяти.
Почти все ячейки видеопамяти могут отображаться на экране. Последние две ячейки, — 1998-ая и 1999-ая, — хранят параметр цвета для фона и параметр цвета для отображаемых ячеек видеопамяти. Возможные цвета[2]:
Значение | Цвет |
---|---|
1 | белый |
2 | зелёный |
3 | голубой или синий |
4 | тёмно-зелёный |
5 | серый |
6 | красный |
7 | жёлтый |
иное | чёрный |
Пример изменения цвета отображаемых ячеек видеопамяти на жёлтый:
mov UR0, 7
vsv UR0, 1999
Для загрузки значения из видеопамяти в п. регистр, используйте команду vld
. Её аргументы:
Синтаксис | Описание |
---|---|
ЦЦЦЦ |
адрес ячейки видеопамяти для загрузки |
ЧИСЛО |
адрес п. регистра-приёмника |
Пример использования:
vld 0001, UR8
Для сохранения значения п. регистра в ячейку видеопамяти, используйте vsv
. Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра для сохранения |
ЦЦЦЦ |
адрес нужной ячейки видеопамяти |
Пример использования:
vsv UR0, 0063
Вы также можете вписывать адрес п. регистра вместо ЦЦЦЦ
в аргументах этих команд (такое поддерживается в Makexm2c). Так, vsv UR0, UR16
сохранит содержимое п. регистра 0 в яч. видеопамяти, адрес которой находится в регистре 16.
Вы можете печатать разными цветами! Для этого, измените ячейку видеопамяти, на месте которой будет изменение цвета последующих, на 255 плюс нужное значение цвета.[2]
Задание
Напишите программу, которая складывает два числа и выводит результат на экран.
Память
правитьПрограммы iiixmish2 загружаются в его па́мять (насколько это возможно).[2] Ограничения кода вне 0-65535:
- нельзя читать/прыгать/писать в 0-65535
- нельзя читать 9999872-9999999
- нельзя изменять 9999000-9999099
- действие инструкции
OFF
равно переходу к 32768
Команда ild
предназначена для загрузки значений из памяти в п. регистры. Аргументы:
Синтаксис | Описание |
---|---|
ЦЦЦЦЦЦЦ |
адрес ячейки памяти для загрузки |
ЧИСЛО |
адрес п. регистра-приёмника. |
Пример использования:
ild 6001900, UR0
Для сохранения значения п. регистра в память, используйте isv
. Аргументы:
Синтаксис | Описание |
---|---|
ЧИСЛО |
адрес п. регистра для сохранения |
ЦЦЦЦЦЦЦ |
адрес нужной ячейки памяти |
Пример использования:
isv UR10, 0999999
Вы можете вписывать адрес п. регистра вместо ЦЦЦЦЦЦЦ
в аргументах этих команд.
Простая программа
правитьНиже представлен пример программы, в которой пользователь может вводить данные. То, что от символа «;» до конца строки будет комментарием.
mov UR28, <loop>
; указатель вывода
mov UR27, 0
; ноль
mov UR0, 0
loop:
; эта команда ничего не делает,
; её выполнение может занимать
; до миллисекунды
nop
; проверка клавиши
if UR1 == UR0, UR28
; сохраняем символ
vsv UR1, UR27
; увеличиваем указатель
inc UR27
; сбрасываем регистр клавиатуры
mov UR1, 0
; обновляем экран
updd
; продолжение
jmp UR28
Задание
Измените программу так, чтобы фон стал белым, а текст, вводимый пользователем, — чёрным. Помните, как собирать и запускать программы?
Ещё директивы
править.ascii <mem0> "hello world"
приказывает ассемблеру записать строку «hello world», начиная с яч. <mem0> (адрес метки mem0). .skip N
пропускает N байтов, это похоже на N nop'ов. .byte ЧИСЛО
вставит десятичное ЧИСЛО. .orig 1000
выполнит переход к ячейке 1000 (следующий после этого код будет записан, начиная с ячейки 1000).
Общение с другими компьютерами
правитьIiixmish2 и другие компьютеры (включая ЭВМ, на котором выполняется iiixmish2) могут «общаться» через порты ввода/вывода. Данные, которые передал компьютер, сохраняются в памяти iiixmish2, начиная с адреса 9999872. Чтобы ответить, запишите краткий ответ, начиная с адреса 9999000.
Это последний раздел изучения. В нём описываются команды off
и vrst
.
off
правитьЕсли off
выполняется в коде 0-65535, то он завершает работу iiixmish2; иначе выполняется переход к 32768.
vrst
правитьvrst
заменяет значения почти всех ячеек видеопамяти на неотображаемое (0), предназначение — убрать текст с экрана.