Перейти к содержанию

Компьютерная архитектура iiixmish2

завершено на 100%
Материал из Викиучебника — открытых книг для открытого мира
(перенаправлено с «Makexm2c»)


Компьютерная архитектура iiixmish2

учебник по языку ассе́мблера Makexm2c и др.



Предисловие[править]

Эта книга является модифицированной совокупностью других учебников по теме iiixmish2. Вы научитесь программировать на языке ассемблера, узнаете об бесфайловой операционной системе…

Определения[править]

Регистр процессора
Регистр процессора — это поле определённой длины, которое находится в памяти процессора. Доступ к регистру очень быстр, его содержимое можно сохранить в память и обратно. Бывает как доступен из программы, так и нет.
Язык ассемблера
Код на Си и как он может выглядеть на языке ассемблера (переменная variable по адресу 8699999)
int variable = 5;
mov %R_FA_0%, 5
isv %R_FA_0%, 8699999
Язык ассемблера — это низкоуровневый язык программирования, максимально приближённый к командам самого процессора. Из-за сильной привязанности к определённой архитектуре, не является переносимым. Противоположность языку ассемблера — более лёгкий и абстрагированный высокоуровневый язык программирования (например, Си).
Ассемблерная директива
Ассемблерная директива («псевдокоманда») — это, можно сказать, команда ассемблера, а не компьютера. Как правило, начинается со спецсимвола (напр., точки). Примеры в Makexm2c — .goto, .ascii и .def.

Язык ассемблера Makexm2c[править]

Введение[править]

Учебник[править]

Данный учебник учит программированию на Makexm2c.

Makexm2c[править]

Makexm2c — это язык ассемблера, предназначенный для создания программ для виртуальной машины «iiixmish2».[1] Если Вы являетесь опытным программистом, то можете найти Makexm2c более лёгким, чем другие низкоуровневые языки.

iiixmish2[править]

Iiixmish2 — это 32-разрядная виртуальная машина со своими командами и др. Она имеет 10 миллионов ячеек памяти, 44 пользовательских регистров, 8 регистров для потоков, 2000 ячеек видеопамяти, более 30 команд и экран 640 × 480 (но может отображаться меньше).[2]

Ниже представлены названия iiixmish2-инструкций и соответствующие signed char-опкоды[3]:

Название Код операции
NOP[4] -1
ADD -2
SUB -3
MOV -4
ILD -5
VLD -6
LD -7
ISV -8
VSV -9
SLP -10
IFA -11
IFB -12
IFC -13
IFD -14
UPDD -15
OFF -16
VRST -17
JMP -18
END -19
SEL -20
MUL -21
DIV -22
LSLP -23
CUR -24
VSTR -25
INC -26
DEC -27
TNP -28
MOD -29
EXP -30
MOV2 -31
TH1 -32
TH2 -33
TH3 -34
MOV3 -35
VSVAN -36
IFE -37
LSHIFT -38
RSHIFT -39
XOR, OR, AND -40, -41, -42

Получение необходимого[править]

Скачайте свободную реализацию iiixmish2 здесь, а также средства для разработки программ на Makexm2c здесь (makexm2c-tools).

Распакуйте полученные архивы. Скомпилируйте программы, используя OpenJDK 17. В Debian, Вы можете установить его, выполнив следующую команду:

$ sudo apt install openjdk-17-jdk

Выполните java --version.

Синтаксис[править]

Makexm2c-программы могут состоять из команд:

<название> [<аргумент 0>[[,] <аргумент 1>]…]

, псевдокоманд (директив):

.<название> [<аргумент 0>[ <аргумент 1>]]

, меток:

<название>:

и комментариев.

К регистрам можно подставлять «UR» (UR0, UR1…).

«Hello, world!»[править]

Теперь мы можем написать программу «Hello, world!», она будет выводить на экран виртуальной машины «Hello, world!» (перевод — «Всем привет!», а буквально — «Здравствуй, мир!»). Программа подобна загрузчику: она выполняется практически сразу после запуска машины и не требует для своей работы операционной системы.

Создайте файл «hello.asm» и вставьте в него следующее:

vstr 0000, "Hello, world!"
updd

Это код на Makexm2c, переведите его в код, понятный виртуальной машине iiixmish2, используя ассемблер из makexm2c-tools:

$ java downadow.makexm2c_tools.main.Assembler hello.asm hello

Отлично! Запустите iiixmish2, передав полученный файл:

$ java downadow.iiixmish2.main.Iiixmish2 hello --no-communication

Параметр --no-communication отключает, возможно, губительную для SSD-дисков коммуникацию. Если требуется, опустите данный параметр, включение и выключение коммуникации контролируется клавишами F2 и F3.[5]

Команды[6][3][править]

Код нашей программы состоит из двух команд — vstr и updd.

vstr[править]

Команда vstr нужна для вывода строки на экран. Конечно, это можно сделать и без неё, но с ней это делается проще и эффективнее: сокращается размер программы. Имеет два аргумента:

Синтаксис Описание
ЦЦЦЦ (Ц — цифра) Адрес ячейки видеопамяти, с которого будет располагаться строка
"СТРОКА" СТРОКА для вывода

updd[править]

Команда для обновления («перерисовки») экрана.

Регистры[править]

Как уже было сказано ранее, iiixmish2 имеет 44 пользовательских регистров (п. реги́стры) и 8 для потоков.

2, 3 и 4 п. регистры предназначены для обновления экрана, п. регистр 1 хранит нажатую клавишу. Избегайте использования п. регистров 5, 7, 9 и 11, т. к. они могут использоваться некоторыми командами (например, vstr и vrst).[3]

Операции[6][3][править]

Присваивание[править]

Команда 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

Возведение в степень[править]

Пример:

exp UR0 UR6, UR8

mov2[править]

Команда mov2 выполняет то же, что и mov, но размер второго аргумента увеличен до шести байтов. Аргументы:

Синтаксис Описание
ЧИСЛО адрес п. регистра
ЦЦЦЦЦЦЦ число для сохранения

Пример использования:

mov2 UR0, 0004985

mov3[править]

Команда mov3 «склеивает» п. регистры как строки, сохраняет результат в п. регистр. Аргументы:

Синтаксис Описание
ЧИСЛО адрес п. регистра, в который следует сохранить результат
ЧИСЛО адрес первого п. регистра для «склеивания»
ЧИСЛО адрес второго п. регистра для «склеивания»
ЧИСЛО адрес третьего п. регистра для «склеивания»
ЧИСЛО адрес четвёртого п. регистра для «склеивания»
ЧИСЛО адрес пятого п. регистра для «склеивания»
ЧИСЛО адрес шестого п. регистра для «склеивания»

Пример использования:

mov3 UR0, UR29 UR28 UR27 UR26 UR25 UR24

Сдвиг[править]

Следующий код выполняет операцию вида UR20 << UR19 (сдвиг битов влево) и сохраняет результат в UR8:

lshift UR20 UR19, UR8

UR8 = UR20 >> UR19:

rshift UR20 UR19, UR8

Для побитовых XOR, OR и AND, используйте одноимённые инструкции.

Генерация числа[править]

Команда sel выбирает число от нуля до ОПРЕДЕЛЁННОГО числа минус один, результат сохраняет в п. регистр. Аргументы:

Синтаксис Описание
ЧИСЛО адрес п. регистра, содержащего ОПРЕДЕЛЁННОЕ число
ЧИСЛО адрес п. регистра, в который следует сохранить результат

Пример использования:

sel UR0, UR12

Комментарии[править]

Коммента́рии — это тексты в коде программы, которые не влияют на её работу, но, как правило, помогают лучше понять её. В Makexm2c нет обязательного спецсимвола, который отличал бы комментарии от команд.[6]

Метки[6][править]

Ме́тки — в Makexm2c — это мнемоники, которые ставятся в определённые места в коде программы. Обращение к метке вставляет на месте обращения адрес, по которому располагается эта метка в двоичной форме программы. Пример:

метка:
    nop
    nop
    mov2 UR0, <метка>

Для обращения, название метки, заключённое в < и >, вставляется в нужное место в программе.

Именованные константы[6][править]

Для создания именованных констант используется директива .def, пример:

.def %CONST% "0"

создаст именованную константу «CONST» со значением «0».

Обращение к именованным константам отличается от обращения к меткам лишь тем, что название заключается в %, а не < и >.

Ветвление[6][3][править]

Задание

Потренируйтесь с пройденными командами.


В iiixmish2 есть команды для создания условных переходов. Рассмотрим, как использовать их в Makexm2c.

Равно[править]

В iiixmish2 нет инструкций вроде BRz, BRn и т. д., ветвление реализуется посредством команд IFA, IFB, IFC, IFD и IFE. Для создания перехода вроде «если значение п. регистра А равно значению регистра Б, то выполнить переход на <значение п. регистра В>», воспользуйтесь следующей конструкцией:

if АДРЕС0 == АДРЕС1, АДРЕС2
Название Описание
АДРЕС0 адрес первого п. регистра для сравнения
АДРЕС1 адрес второго п. регистра для сравнения
АДРЕС2 адрес п. регистра, на значение которого нужно перейти


Ясно? Идём дальше.

Неравно[править]

if АДРЕС0 != АДРЕС1, АДРЕС2

Больше[править]

if АДРЕС0 > АДРЕС1, АДРЕС2

Меньше[править]

if АДРЕС0 < АДРЕС1, АДРЕС2

Равно ×2[править]

if АДРЕС0 == АДРЕС1 && АДРЕС2 == АДРЕС3, АДРЕС4

(если п. регистры АДРЕС0 и АДРЕС1 равны, п. регистры АДРЕС2 и АДРЕС3 равны, то выполнить переход на <значение п. регистра АДРЕС4>)

Видеопамять[править]

Как уже говорилось во введении, iiixmish2 имеет 2000 ячеек видеопамяти.

Почти все ячейки видеопамяти могут отображаться на экране. Последние две ячейки, — 1998-ая и 1999-ая, — хранят параметр цвета для фона и параметр цвета для отображаемых ячеек видеопамяти. Возможные цвета[3]:

Значение Цвет
1 белый
2 зелёный
3 голубой или синий
4 тёмно-зелёный
5 серый
6 красный
7 жёлтый
иное чёрный


Пример изменения цвета отображаемых ячеек видеопамяти на жёлтый:

mov UR0, 7
vsv UR0, 1999

Загрузка и сохранение[6][3][править]

Для загрузки значения из видеопамяти в п. регистр, используйте команду vld. Её аргументы:

Синтаксис Описание
ЦЦЦЦ адрес ячейки видеопамяти для загрузки
ЧИСЛО адрес п. регистра-приёмника

Пример использования:

vld 0001, UR8


Для сохранения значения п. регистра в ячейку видеопамяти, используйте vsv. Аргументы:

Синтаксис Описание
ЧИСЛО адрес п. регистра для сохранения
ЦЦЦЦ адрес нужной ячейки видеопамяти

Пример использования:

vsv UR0, 0063


Для сохранения значения п. регистра в видеопамять как число, используйте vsvan. Аргументы:

Синтаксис Описание
ЧИСЛО адрес п. регистра для сохранения
ЦЦЦЦ адрес ячейки видеопамяти, с которой следует начать запись

Пример использования:

vsvan UR0, 0000


Вы также можете вписывать адрес п. регистра вместо ЦЦЦЦ в аргументах этих команд (такое поддерживается в Makexm2c). Так, vsv UR0, UR16 сохранит содержимое п. регистра 0 в яч. видеопамяти, адрес которой находится в регистре 16.

Вы можете печатать разными цветами! Для этого, измените ячейку видеопамяти, на месте которой будет изменение цвета последующих, на 255 плюс нужное значение цвета.[3]

Текст в самой нижней строке отображается полужирным.

Задание

Напишите программу, которая складывает два числа и выводит результат на экран.

Вывод линий[править]

Для вывода линии, дайте значение цвета (отличное от нуля) ячейке видеопамяти 1900 + НОМЕР_ЛИНИИ * 5 и дайте x1, y1, x2, y2 (например, 200, 100, 280, 101) следующим ячейкам после неё.

Память[править]

Программы iiixmish2 загружаются в его па́мять (насколько это возможно).[3]

Загрузка и сохранение[6][3][править]

Команда ild предназначена для загрузки значений из памяти в п. регистры. Аргументы:

Синтаксис Описание
ЦЦЦЦЦЦЦ адрес ячейки памяти для загрузки
ЧИСЛО адрес п. регистра-приёмника.

Пример использования:

ild 6001900, UR0

Для сохранения значения п. регистра в память, используйте isv. Аргументы:

Синтаксис Описание
ЧИСЛО адрес п. регистра для сохранения
ЦЦЦЦЦЦЦ адрес нужной ячейки памяти

Пример использования:

isv UR10, 0999999


Вы можете вписывать адрес п. регистра вместо ЦЦЦЦЦЦЦ в аргументах этих команд.

Многопоточность[править]

В iiixmish2 встроены команды TH1, TH2 и TH3. Используя их, вы можете выполнять задачи одновременно. Эти команды имеют один аргумент — адрес п. регистра, со значения которого следует начать новую задачу.[3] Пример программы:

mov2 UR0, <thread>
th1 UR0
end
thread:
    vstr 0000, "OK!"
    updd

Недостаток vstr[править]

Максимальное значение символа в vstr-строке ограничено одним байтом[3], т. е. вы не можете печатать дополнительные символы на экран iiixmish2, используя эту команду (например, буквы русского алфавита). Длина vstr-строки не должна превышать один знаковый байт (signed char).

Но есть Java-программа Print, которая поставляется с выпуском makexm2c-tools. Использование[7]:

$ java downadow.makexm2c_tools.main.Print [-r|--user-register АДРЕС] [-a|--address АДРЕС] "СТРОКА"

Эта программа выводит Makexm2c-код, который должен выводить любой доступный символ на экран iiixmish2; но код, который он создаёт, нехорош, т. к. программа не оптимизирует сохранение в видеопамять повторяющихся символов, из-за чего код получается большим.

Задание

Напишите программу, которая выводит «Здравствуй, мир!», используя Print из makexm2c-tools.

Простая программа[править]

Ниже представлен пример программы, в которой пользователь может вводить данные. То, что от символа «;» до конца строки будет комментарием.

mov UR29, 30
mov2 UR28, <main>

main:
    ; ждать 30 миллисекунд
    lslp UR29
    ; если клавиша не была нажата, то перейти к main
    if UR1 == UR0, UR28
    ; сохраняем клавишу (указателем текущей ячейки будет п. регистр 27)
    vsv UR1, UR27
    ; увеличиваем указатель
    inc UR27
    ; сбрасываем нажатую клавишу
    mov UR1, 0
    ; обновляем экран
    updd
    
    ; переход к main
    jmp UR28


Задание

Измените программу так, чтобы фон стал белым, а текст, вводимый пользователем, — чёрным. Помните, как собирать и запускать программы?

.ascii и .goto[править]

.ascii <mem0> "hello world" приказывает ассемблеру записать строку «hello world», начиная с яч. <mem0> (адрес метки mem0). .goto +100 приказывает перейти ассемблеру на 100 яч. больше, это похоже на 100 nop'ов.

Общение с другими компьютерами[править]

Iiixmish2 и другие компьютеры (включая ЭВМ, на котором выполняется iiixmish2) могут «общаться» через файлы коммуникации. Данные, которые передал компьютер, сохраняются в памяти iiixmish2, начиная с адреса 9999872. Чтобы ответить, запишите краткий ответ, начиная с адреса 9999000.

Ещё команды[6][править]

Это последний раздел изучения. В нём описываются команды slp, off, vrst и end.

slp[править]

slp ждёт <значение п. регистра А> секунд (для миллисекунд есть lslp). Пример использования:

slp UR0

off[править]

off завершает работу iiixmish2.

vrst[править]

vrst заменяет значения почти всех ячеек видеопамяти на неотображаемое (0), предназначение — убрать текст и линии с экрана. Не путайте его с vstr.

end[править]

Если цикл выполнения памяти встретит команду end, то он должен будет завершиться.


Задание

Напишите программу, которая должна завершиться тогда, когда пользователь нажмёт какую-нибудь клавишу.

Xmtwolime[править]

Введение[8][править]

Xmtwolime — это операционная система, которая уважает вашу свободу. Работает на виртуальной машине iiixmish2 и не выполняет операций над файлами.

Требования[править]

Вы должны иметь:

  • Java Runtime Environment и Java Development Kit (>= 8; OpenJDK подойдёт)
  • iiixmish2
  • makexm2c-tools
  • компилятор Си
  • GNU bash
  • зависимости вышеперечисленных пакетов

Сборка…[править]

Ниже показаны инструкции для GNU+Linux. Для других ОС, действия могут отличаться.

…iiixmish2 и makexm2c-tools[править]

$ cd iiixmish2/
$ bash build.sh
$ cd ../makexm2c-tools
$ bash build.sh

…системы[править]

$ cd xmtwolime/
$ bash build.sh </путь/к/makexm2c-tools> <устройство> # «ls etc» для получения списка доступных «устройств»

Информацию при выводе можно использовать для GetPart из makexm2c-tools, чтобы получить конкретный раздел из образа системы.

Загрузка[править]

Запустите iiixmish2:

$ cd iiixmish2/
$ java downadow.iiixmish2.main.Iiixmish2 <путь к каталогу xmtwolime>/image --no-communication

Если ничего не нажимать, должна пойти нормальная загрузка системы. Если нажать клавишу «f», то загрузка пойдёт в FastBoot, где, при условии разблокированного состояния, можно прошивать файлы, используя xtl-fastboot-tool (в таком случае, отпустите параметр --no-communication при запуске машины). Если же нажать «r», то загрузится «рекавери».

Работа с Xmtwolime[править]

Войдите в систему как «обычный пользователь», оставив поле ввода пустым.

sed 8700000 STRока запишет строку «STRока», начиная с ячейки памяти 8700000. bed 9000200 0001024 (набирать точно так, как показано) положит число 1024 в ячейку 9000200. Команда tnp изменяет знак яч. памяти. str 8700003 покажет содержимое памяти, начиная с яч. 8700003. vwb показывает значение ячейки памяти (формат как у txt). gam запустит игру. txt 9000000 начнёт записывать пользовательский ввод в память, начиная с ячейки 9000000. thm выведет информацию о цветах. thm 1 0 изменит цвет фона на белый, а цвет текста — на чёрный. Программа who печатает идентификатор пользователя (UID). Есть и другие программы.

Архитектура[9][править]

Сперва, выполняется код программы-загрузчика bootrom. По умолчанию, он просто переходит к коду xloader, но, как правило, bootrom также включает программу прошивки (edl или brom)[10].

Раздел xloader содержит ещё один загрузчик, который:

  • выполняет переход к началу кода fastboot, либо
  • переходит к fastboot RESCUE_MODE, либо
  • загружается в recovery

Следующий раздел, fastboot, хранит программу перехода к коду ядра операционной системы (<boot_start>), а также содержит программу RESCUE_MODE, которую можно использовать для прошивки нового recovery, system и т. д. (bootrom прошивать там нельзя).

recovery содержит программу восстановления (в частности, имеется возможность стереть пользовательские данные). В неё можно попасть, нажав «r» при загрузке. Образец программы представлен ниже:

recovery_start:
	mov UR1, 0	
	
	mov UR16, 0
	;; смена цвета ячеек видеопамяти на чёрный
	vsv UR16, 1999
	
	mov UR16, 1
	;; смена цвета фона на белый
	vsv UR16, 1998
	
	vrst
	
	vstr 0028, "RECOVERY"
	vstr 0126, " [1]  erase userdata"
	vstr 0189, " [2]  full reboot"
	updd
	
	recovery_loop:
		mov UR29, 60
		lslp UR29
		mov UR29, '1'
		mov2 UR28, <recovery_loop_1>
		if UR1 == UR29, UR28
		mov UR29, '2'
		mov2 UR28, <recovery_loop_2>
		if UR1 == UR29, UR28
		
		mov2 UR28, <recovery_loop>
		jmp UR28
		
		recovery_loop_1:
			mov2 UR29, 6900000
			mov2 UR28, 9999999
			mov2 UR25, <xloader_start2>
			
			mov UR0, 0
			mov2 UR20, <recovery_loop_1_eraseLoop>
			isv UR0, UR28
			
			recovery_loop_1_eraseLoop:
				isv UR0, UR29
				
				inc UR29
				
				if UR29 < UR28, UR20
			
			jmp UR25
		
		recovery_loop_2:
			mov UR29, 0
			jmp UR29


recovery_end:
	nop

Раздел info содержит информацию о «pkey» (это код, на основе которого генерируется код разблокировки загрузчика), ключ разблокировки fastboot RESCUE_MODE (используется не всегда!), состояние загрузчика (1 — заблокирован, 0 — разблокирован). Попробуйте перезаписать его.

boot содержит ядро операционной системы, а system — остальные её данные (например, анимация загрузки и приложения).

userdata может содержать данные программ, хранящих значения в памяти, и, конечно же, данные «обычного пользователя» (начинаются с ячейки 8700000).

Xmtwolime не знает слова «файл», не пугайтесь данной особенности. Память можно разделить на вышеупомянутые разделы.

Написание программного обеспечения[править]

Пример программы на Makexm2c
;; эта программа выводит свои аргументы
ech:
	mov %R_FA_0%, %ARGS_ST%
	mov %R_FA_1%, %OUT_ST%
	
	mov %R_FA_2%, %OUT_ST%
	mov2 %R_FA_3%, <ech_loop>
	
	ech_loop:
		vld %R_FA_0%, %R_FA_4%
		vsv %R_FA_4%, %R_FA_1%
		
		inc %R_FA_0%
		inc %R_FA_1%
		
		if %R_FA_0% < %R_FA_2%, %R_FA_3%
	
	updd
	%__END_THE_APP__%

Makexm2c — это язык ассемблера для iiixmish2. Xmtwolime-программы написаны на нём.

Программирование под Xmtwolime[править]

Введение[править]

Эта книга повествует о создании программ под Xmtwolime, используя язык Makexm2c. Можете считать её продолжением учебника Makexm2c.

Вид[править]

Xmtwolime-программы имеют следующий вид:

; ...

имяпрограммы:
    ; код

Имя программы должно состоять ровно из трёх ASCII-символов![11] Всегда начинайте метки и им. константы программы с её названия!

Hello, world![править]

Переместитесь в каталог xmtwolime. Создайте файл software/hey.s со следующим содержимым:

hey:
    vstr %OUT_ST%, "Hello, world!"
    mov %R_RETURN_CODE%, 0
    %__END_THE_APP__%

Это Makexm2c-программа для Xmtwolime. Соберите систему, запустите её в виртуальной машине. Наберите в оболочке «hey», на экране должно появится «Hello, world!».

Им. константы[12][править]

Код ядра Xmtwolime содержит множество определений:

	;; пользовательский регистр 29 хранит ID пользователя
	;    0 — root (суперпользователь)
	;    иное — обычный пользователь
	.def %R_USER% "UR29"

	;; п. регистры, которые предназначены для приложений;
	;; но это не запрещает использование их ядром
	.def %R_FA_0% "UR28"
	.def %R_FA_1% "UR27"
	.def %R_FA_2% "UR26"
	.def %R_FA_3% "UR25"
	.def %R_FA_4% "UR24"
	.def %R_FA_5% "UR23"
	.def %R_FA_6% "UR22"
	.def %R_FA_7% "UR21"
	.def %R_FA_8% "UR20"
	.def %R_FA_9% "UR19"
	.def %R_FA_10% "UR18"
	.def %R_FA_11% "UR30"
    .def %R_FA_12% "UR31"
    .def %R_FA_13% "UR32"
    .def %R_FA_14% "UR33"
    .def %R_FA_15% "UR34"
    .def %R_FA_16% "UR35"
    .def %R_FA_17% "UR36"
    .def %R_FA_18% "UR37"
    .def %R_FA_19% "UR38"
    .def %R_FA_20% "UR39"
    .def %R_FA_21% "UR40"
    .def %R_FA_22% "UR41"
    .def %R_FA_23% "UR42"
    .def %R_FA_24% "UR43"

	;; используйте п. регистр 6 как содержащий код возврата
	;; ваших программ
	.def %R_RETURN_CODE% "UR6"

	.def %__END_THE_APP__% "jmp UR17"

	;; адрес начала аргументов приложения в видеопамяти
	.def %ARGS_ST% "0006"
	
	.def %R_ZERO% "UR0"

	;; начало и конец пространства данных обычного пользователя
	.def %ORDINARY_USER_SPACE_ST% "8700000"
	.def %ORDINARY_USER_SPACE_ND% "9999999"

	;; адрес начала раздела вывода
	.def %OUT_ST% "0126"

	.def %R_KEY% "UR1"

Безопасность[править]

Программы находятся в разделе system и имеют полный доступ к памяти, независимо от UID. Создавайте безопасное ПО!

Получение числа из аргумента в форме ЦЦЦЦЦЦЦ (например, 0001024) и сохранение его в п. регистр %R_FA_0%[править]

mov %R_FA_8%, 48

vld 0006, %R_FA_1%
sub %R_FA_1% %R_FA_8%, %R_FA_1%

vld 0007, %R_FA_2%
sub %R_FA_2% %R_FA_8%, %R_FA_2%

vld 0008, %R_FA_3%
sub %R_FA_3% %R_FA_8%, %R_FA_3%

vld 0009, %R_FA_4%
sub %R_FA_4% %R_FA_8%, %R_FA_4%

vld 0010, %R_FA_5%
sub %R_FA_5% %R_FA_8%, %R_FA_5%

vld 0011, %R_FA_6%
sub %R_FA_6% %R_FA_8%, %R_FA_6%

vld 0012, %R_FA_7%
sub %R_FA_7% %R_FA_8%, %R_FA_7%

mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
mov2 %R_FA_2%, 1000000
mul %R_FA_2% %R_FA_1%, %R_FA_1%
add %R_FA_0% %R_FA_1%, %R_FA_0%

Пример программы[править]

;; данная программа выводит результат операции, пример запуска:    ;;
;     clc 0000998 - 0010000                                         ;
clc:
	vld 0014, %R_FA_0%
	
	mov %R_FA_1%, '+'
	mov2 %R_FA_2%, <clc_add>
	if %R_FA_0% == %R_FA_1%, %R_FA_2%
	
	mov %R_FA_1%, '-'
	mov2 %R_FA_2%, <clc_sub>
	if %R_FA_0% == %R_FA_1%, %R_FA_2%
	
	vld 0015, %R_FA_3%
	mov %R_FA_1%, '*'
	mov2 %R_FA_2%, <clc_exp>
	if %R_FA_0% == %R_FA_1% && %R_FA_3% == %R_FA_1%, %R_FA_2%
	
	mov2 %R_FA_2%, <clc_mul>
	if %R_FA_0% == %R_FA_1%, %R_FA_2%
	
	mov %R_FA_1%, '/'
	mov2 %R_FA_2%, <clc_div>
	if %R_FA_0% == %R_FA_1%, %R_FA_2%
	
	mov %R_FA_1%, '%'
	mov2 %R_FA_2%, <clc_mod>
	if %R_FA_0% == %R_FA_1%, %R_FA_2%
	
	;; иначе
	vstr %OUT_ST%, "unknown operation"
	mov %R_RETURN_CODE%, 1
	%__END_THE_APP__%
	
	clc_add:
		;;; получение первого числа
		
		mov %R_FA_8%, 48
		
		vld 0006, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0007, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0008, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0009, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0010, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0011, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0012, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_0% %R_FA_1%, %R_FA_0%
		
		;;; получение второго числа
		
		mov %R_FA_8%, 48
		
		vld 0016, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0017, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0018, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0019, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0020, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0021, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0022, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_8%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_8% %R_FA_1%, %R_FA_8%
		
		;;; сложение
		add %R_FA_0% %R_FA_8%, %R_FA_0%
		
		;;; печать результата
		vsvan %R_FA_0%, %OUT_ST%
		updd
		
		;;; выход
		%__END_THE_APP__%
	
	clc_sub:
		;;; получение первого числа
		
		mov %R_FA_8%, 48
		
		vld 0006, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0007, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0008, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0009, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0010, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0011, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0012, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_0% %R_FA_1%, %R_FA_0%
		
		;;; получение второго числа
		
		mov %R_FA_8%, 48
		
		vld 0016, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0017, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0018, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0019, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0020, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0021, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0022, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_8%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_8% %R_FA_1%, %R_FA_8%
		
		;;; вычитание
		sub %R_FA_0% %R_FA_8%, %R_FA_0%
		
		;;; печать результата
		vsvan %R_FA_0%, %OUT_ST%
		updd
		
		;;; выход
		%__END_THE_APP__%
	
	clc_mul:
		;;; получение первого числа
		
		mov %R_FA_8%, 48
		
		vld 0006, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0007, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0008, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0009, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0010, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0011, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0012, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_0% %R_FA_1%, %R_FA_0%
		
		;;; получение второго числа
		
		mov %R_FA_8%, 48
		
		vld 0016, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0017, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0018, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0019, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0020, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0021, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0022, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_8%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_8% %R_FA_1%, %R_FA_8%
		
		;;; умножение
		mul %R_FA_0% %R_FA_8%, %R_FA_0%
		
		;;; печать результата
		vsvan %R_FA_0%, %OUT_ST%
		updd
		
		;;; выход
		%__END_THE_APP__%
	
	clc_exp:
		;;; получение первого числа
		
		mov %R_FA_8%, 48
		
		vld 0006, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0007, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0008, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0009, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0010, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0011, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0012, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_0% %R_FA_1%, %R_FA_0%
		
		;;; получение второго числа
		
		mov %R_FA_8%, 48
		
		vld 0017, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0018, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0019, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0020, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0021, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0022, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0023, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_8%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_8% %R_FA_1%, %R_FA_8%
		
		;;; возведение
		exp %R_FA_0% %R_FA_8%, %R_FA_0%
		
		;;; печать результата
		vsvan %R_FA_0%, %OUT_ST%
		updd
		
		;;; выход
		%__END_THE_APP__%
	
	clc_div:
		;;; получение первого числа
		
		mov %R_FA_8%, 48
		
		vld 0006, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0007, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0008, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0009, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0010, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0011, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0012, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_0% %R_FA_1%, %R_FA_0%
		
		;;; получение второго числа
		
		mov %R_FA_8%, 48
		
		vld 0016, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0017, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0018, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0019, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0020, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0021, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0022, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_8%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_8% %R_FA_1%, %R_FA_8%
		
		;;; деление
		div %R_FA_0% %R_FA_8%, %R_FA_0%
		
		;;; печать результата
		vsvan %R_FA_0%, %OUT_ST%
		updd
		
		;;; выход
		%__END_THE_APP__%
	
	clc_mod:
		;;; получение первого числа
		
		mov %R_FA_8%, 48
		
		vld 0006, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0007, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0008, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0009, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0010, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0011, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0012, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_0%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_0% %R_FA_1%, %R_FA_0%
		
		;;; получение второго числа
		
		mov %R_FA_8%, 48
		
		vld 0016, %R_FA_1%
		sub %R_FA_1% %R_FA_8%, %R_FA_1%
		
		vld 0017, %R_FA_2%
		sub %R_FA_2% %R_FA_8%, %R_FA_2%
		
		vld 0018, %R_FA_3%
		sub %R_FA_3% %R_FA_8%, %R_FA_3%
		
		vld 0019, %R_FA_4%
		sub %R_FA_4% %R_FA_8%, %R_FA_4%
		
		vld 0020, %R_FA_5%
		sub %R_FA_5% %R_FA_8%, %R_FA_5%
		
		vld 0021, %R_FA_6%
		sub %R_FA_6% %R_FA_8%, %R_FA_6%
		
		vld 0022, %R_FA_7%
		sub %R_FA_7% %R_FA_8%, %R_FA_7%
		
		mov3 %R_FA_8%, %R_FA_2% %R_FA_3% %R_FA_4% %R_FA_5% %R_FA_6% %R_FA_7%
		mov2 %R_FA_2%, 1000000
		mul %R_FA_2% %R_FA_1%, %R_FA_1%
		add %R_FA_8% %R_FA_1%, %R_FA_8%
		
		;;; получение остатка от деления
		mod %R_FA_0% %R_FA_8%, %R_FA_0%
		
		;;; печать результата
		vsvan %R_FA_0%, %OUT_ST%
		updd
		
		;;; выход
		%__END_THE_APP__%

XTLD-«бутрумы» и «фастбут»[править]

Введение[править]

В данном учебнике, мы рассмотрим Xmtwolime-bootrom'ы и протокол FastBoot, по которому идёт коммуникация хост-машины с устройством в режиме RESCUE_MODE.

Нормальная загрузка такова: bootrom → xloader → fastboot → ОС. Подробности можно найти в учебнике по Xmtwolime.

xtld1xx[13][править]

Загрузчик Boot ROM содержит программу «edl». Используя её, можно прошить загрузчик во временное место и загрузиться в него, а в нём уже прошить оставшиеся файлы. Для всего этого есть IDT (в частности, xtl-idt). Протокол схож с FastBoot RESCUE_MODE.

xtld235[править]

Boot ROM xtld235 отличается от предыдущих тем, что в «edl» можно шить xloader и fastboot напрямую, но не более того! Есть и другие изменения.

xtld3xx[14][править]

Некоторые изменения:

  1. «brom» вместо «edl»
    1. требование auth-кода перед прошивкой
    2. нельзя прошивать лишь сам Boot ROM
    3. «@» вместо «-» в отрицательных числах (напр., -60 будет @0000060)
    4. вход по «Delete», а не «Esc»
  2. изменения в FastBoot

Июнь, 2024 год. Неизвестно о какой-либо программе наподобие xtl-idt для xtld3xx.

Фрагмент кода прошивки[править]

			brom_rescueMode_loop_flash:
				mov UR1, 0
				mov UR29, 0
				isv UR29, 9999872
				isv UR29, 9999881
				
				mov UR16, 1
				;; смена цвета ячеек видеопамяти на белый
				vsv UR16, 1999
				updd
				
				;;; получение адреса ячейки памяти
				
				mov UR20, 48
				
				ild 9999887, UR13
				sub UR13 UR20, UR13
				
				ild 9999888, UR14
				sub UR14 UR20, UR14
				
				ild 9999889, UR15
				sub UR15 UR20, UR15
				
				ild 9999890, UR16
				sub UR16 UR20, UR16
				
				ild 9999891, UR17
				sub UR17 UR20, UR17
				
				ild 9999892, UR18
				sub UR18 UR20, UR18
				
				ild 9999893, UR19
				sub UR19 UR20, UR19
				
				mov3 UR12, UR14 UR15 UR16 UR17 UR18 UR19
				mov2 UR14, 1000000
				mul UR14 UR13, UR13
				add UR12 UR13, UR12
				
				;;; запрещаю шить bootrom
				
				mov2 UR28, <bootrom_end>
				mov2 UR27, <brom_rescueMode_loop>
				
				if UR12 < UR28, UR27
				
				;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
				
				brom_rescueMode_loop_flash_write:
					;;; получение значения
					
					mov UR20, 48
					
					ild 9999896, UR13
					sub UR13 UR20, UR13
					
					ild 9999897, UR14
					sub UR14 UR20, UR14
					
					ild 9999898, UR15
					sub UR15 UR20, UR15
					
					ild 9999899, UR16
					sub UR16 UR20, UR16
					
					ild 9999900, UR17
					sub UR17 UR20, UR17
					
					ild 9999901, UR18
					sub UR18 UR20, UR18
					
					ild 9999902, UR19
					sub UR19 UR20, UR19
					
					mov3 UR20, UR14 UR15 UR16 UR17 UR18 UR19
					mov2 UR14, 1000000
					mul UR14 UR13, UR13
					add UR20 UR13, UR20
					
					mov UR14, '@'
					mov2 UR15, <brom_rescueMode_loop_flash_write_m>
					ild 9999895, UR13
					if UR13 == UR14, UR15
					
					mov2 UR15, <brom_rescueMode_loop_flash_write_continue>
					jmp UR15
					
					brom_rescueMode_loop_flash_write_m:
						tnp UR20
					
					;;;;;;;;;;;;;;;;;;;;;;
					
					brom_rescueMode_loop_flash_write_continue:
						isv UR20, UR12

FastBoot-протокол[15][править]

XTLD-устройство в режиме FastBoot RESCUE_MODE и хост-машина могут «общаться», отвечая и присылая команды в файлы .comm2 и .comm.

Так, fastboot flash [ЦЦЦЦЦЦЦ[16] { |-}ЦЦЦЦЦЦЦ]… — изменение содержимого ячейки памяти, повторение не более трёх раз. Пример изменения ячейки 40000 на 11, обратите внимание на два пробела вместо одного: fastboot flash 0040000  0000011. Есть и другие команды, как, например, fastboot reboot.

Ниже представлен образец получения состояния загрузчика на Java, которое сохраняется FastBoot'ом во второй байт .comm2; используется xm2commlib:

if(new Xm2("/path/to/iiixmish2").getAnswer()[1] == 0)
    System.out.println("unlocked");
else
    System.out.println("locked");

Небольшой фрагмент[править]


	fastboot_clear_comm2_0_byte:
		mov UR29, 0
		isv UR29, 9999000
	
	fastboot_clear_command:
		mov UR29, 0
		isv UR29, 9999872
		isv UR29, 9999881
		isv UR29, 9999888
	
	fastboot_rescueMode_loop:
		ild <info_BSTATE>, UR29
		isv UR29, 9999001
		
		mov UR29, 5
		lslp UR29
		mov UR29, 32
		mov2 UR28, <xloader_start2>
		mov UR27, 2
		
		if UR1 == UR29, UR28
		mov UR28, 0
		updd
		
		;;; интерпретация команд
		
		ild 9999872, UR16
		ild 9999881, UR17
		
		mov UR13, 'f'
		
		mov UR14, 'l'
		mov2 UR15, <fastboot_lock>
		if UR16 == UR13 && UR17 == UR14, UR15
				
		mov2 UR15, <fastboot_rescueMode_loop_flash>
		if UR16 == UR13 && UR17 == UR13, UR15
		
		ild 9999881, UR16
		ild 9999888, UR17
		
		mov UR13, 'r'
		
		mov UR14, 'b'
		mov2 UR15, <fastboot_rescueMode>
		if UR16 == UR13 && UR17 == UR14, UR15
		
		ild 9999872, UR16
		ild 9999881, UR17
		
		mov UR13, 'f'
		
		mov UR14, 'r'
		mov2 UR15, <xloader_start2>
		if UR16 == UR13 && UR17 == UR14, UR15
		
		mov UR13, 'e'
		ild 9999881, UR16
		ild 9999887, UR17
		mov2 UR25, <fastboot_clear_command>
		
		mov UR14, 'x'
		mov2 UR29, <xloader_start>
		mov2 UR28, <xloader_end>
		mov2 UR15, <fastboot_erase>
		if UR16 == UR13 && UR17 == UR14, UR15
		
		mov UR14, 'b'
		mov2 UR29, <boot_start>
		mov2 UR28, <boot_end>
		mov2 UR15, <fastboot_erase>
		if UR16 == UR13 && UR17 == UR14, UR15
		
		mov UR14, 's'
		mov2 UR29, <system_start>
		mov2 UR28, 6899999
		mov2 UR15, <fastboot_erase>
		if UR16 == UR13 && UR17 == UR14, UR15
		
		mov UR14, 'u'
		mov2 UR29, 6900000
		mov2 UR28, 9999999
		mov2 UR15, <fastboot_erase>
		if UR16 == UR13 && UR17 == UR14, UR15
		
		;;;;;;;;;;;;;;;;;;;;;;;;
		
		mov UR1, 0
		mov2 UR28, <fastboot_rescueMode_loop>
		jmp UR28
		
		fastboot_rescueMode_loop_flash:

Примечания[править]