GBA ASM - День 1: Постигаем ассемблер — Архив WASM.RU
Вы можете спросить, будем ли мы использовать тот же ассемблер, который идёт вместе с GCC. Короткий ответ: НЕТ. Развёрнутый ответ: мы будем использовать ассемблер Goldroad, который можно найти на его сайте или скачать здесь. Я использую версию 1.6F. Вам следует скачать самую последнюю версию ассемблера и распаковать её куда-нибудь, так чтобы в пути не было пробелов. Если в пути нет пробелов - это всегда существенно облегчает жизнь.
Оки, вы распаковали ассемблер туда, куда хотели. У меня есть файл, который может вам изрядно помочь. Это screen.h из туториала Pern'а, который я вручную сконвертировал в синтаксис ассемблера Goldroad. Скачайте его здесь и поместите в ту же директорию, где находится Goldroad.exe.
Теперь вы наверняка захотите проверить, как он работает. Но для начала вам нужен эмулятор. Идите и найдите VisualboyAdvance, так как я на 100% уверен, что он понимает командную строку. Чтобы проверить, как он работает, создайте файл first.asm, скопируйте в него нижеследующий исходник и поместите в ту же директорию, где находится ассемблер.
Код (Text):
; начинайте копировать отсюда @include screen.h @textarea ldr r1,=REG_DISPCNT ldr r2,=(BG2_ENABLE|MODE_3) str r2,[r1] ldr r1,=0x0FF ldr r2,=vram+2410 str r1,[r2] label1 B label1 @pool @endarea ; заканчивайте копировать здесьАльтернативный код на C будет примерно следующим:
Код (Text):
int main() { SetMode(MODE_3|BG2_ENABLE); vram[2410] = 0x0FF; while(1) {} }Тем не менее, как вы вероятно знаете, скомпилированный C-код будет ОГРОМНЫМ. Только ассемблер может дать вам маленькие бинарники. Давайте проанализируем исходник строка за строкой.
Код (Text):
@include screen.hЭта строка делает то же самое, что и выражение #include в C.
Код (Text):
@textareaЭта строка просто определяет, где начинается код.
Код (Text):
ldr r1,=REG_DISPCNTО, вот и первая настоящее ассемблерное выражение. Здесь в дело вступаю я.
В ARM'е (процессор GBA) есть 16 регистров r0-r15. r15 - это вроде IP (Instruction Pointer) в процессорах Intel. ОСТАВЬТЕ ЕГО В ПОКОЕ! Я стараюсь работать только с первыми 10 - r0-r9. Если вы знаете Intel- или x86-ассемблер, тогда вы ПОЧТИ знаете инструкции MOV и LDR. Эти инструкции позволяют вам перемещать 32-х битные числа. Второй операнд (число/регистр) перемещается в первый (число/регистр). Инструкция MOV используется только в особых случаях. Мы пока будем использовать LDR, которая расшифровывается как LoaD Register (загрузить в регистр). Она загружает в указанный регистр значение другого регистра, либо ячейки памяти, либо заданного числа. Давай вернёмся к нашей строке кода:
Код (Text):
ldr r1,=REG_DISPCNT * Это инструкция LDR. * Первым параметром в нашем случае является регистр r1. * REG_DISPCNT задан в screen.h и определяет местонахождение памяти управления экраном.Используйте звёздочки, чтобы определить к чему относятся комментарии.
Код (Text):
ldr r2,=(BG2_ENABLE|MODE_3)Здесь то же самое, что и в предыдщущей строке, только на этот раз вторым операндом являются два сORенных значения (оператор '|'). BG2_ENABLE и MODE_3 заданы в screen.h и будучи сORенными дают значение 0x0403. Это значение помещается в регистр r2.
Код (Text):
str r2,[r1]Вау, наша вторая инструкция, инструкция STR помещает значение первого регистра в ячейку памяти, задаваемую вторым операндом. STR расшифровывается как STore Register (сохранить регистр). В данном случае квадратные скобки [] говорят, что регистр используется как указатель. Знаете что? Эти три инструкции делают то, что в C для нас делает SetMode(MODE_3|BG2_ENABLE). Это переводит экран в битмэп-режим номер три (3).
Код (Text):
ldr r1,=0x0FFСейчас вы должны это понять - это загружает в r1 0x0FF (255).
Код (Text):
ldr r2,=vram+2410Вы должны понять и этом, за исключением того, что я сейчас объясню. Для начала, просто чтобы вы знали, vram также задаётся в screen.h, и это память, в которую вам понадобится писать, чтобы вывести что-нибудь на экран. vram определяется как 0x06000000.
Теперь наша инструкция прибавляет 2410 к значению vram, загружая значение в r2. Почему? Чтобы поместить значение цвета вам нужно задать x и y, верно? Поэтому вот формула для 3-его режима:
Код (Text):
y * 240 + xСоответственно наша инструкция задаёт позицию x=10, y=10. Более того, 0x0FF, который мы ранее поместили в r1, будет означать ярко-красный цвет, когда мы поместитм точку на экран.
Код (Text):
str r1,[r2]Снова инструкция str, только в этом раз мы помещаем содержимое регистра r1 в ячейку памяти, на которую указывает r2. В данном случае r2 указывает на экранную координату 10,10, а r1 - это ярко-красный цвет. Таким образом, сохранение ярко-красного цвета в экранную память в позиции 10,10... Позже я дам вам увидеть результат. Но пока ещё немного кода.
Код (Text):
label1Задаёт метку, к которой вы можете перейти подобно тому, как работает команда goto в BASIC.
Код (Text):
b label1Эквивалентно 'Goto label1' в BASIC'е. Эти две строки создают бесконечный цикл. Инструкция B работает подобно инструкции Jxxx в x86-ассемблере, она передаёт управление в зависимости от результата предыдущих операций, подробнее об этом будет написано дальше.
Код (Text):
@poolДаёт ассемблеру место, куда можно поместить некоторые из чисел, которые мы задавали и использовали. АБСОЛЮТНО НЕОБХОДИМО.
Код (Text):
@endareaГоворит ассемблеру, что секция кода закончена.
Эй, мы только что закончили с нашей первой программой под GBA на ассемблере!
Компилирование нашего исходника
Я предполагаю, что вы работаете в Windows, да и один совет - ПОСТАВЬТЕ XP! (Второй совет от переводчика - СНЕСИТЕ XP!)
Наберите 'goldroad first.asm' в директории, где находится Goldroad Assembler и нажмите ввод.
Если вы увидели какие-нибудь сообщения об ошибках, попробуйте снова, убедитесь, что задали команду верно.
Если вы увидели "Assembled successfully" или что-нибудь вроде этого, поздравляю!
Если всё прошло как надо, то в папке Goldroad'а должен появиться файл first.gba.
Теперь осталось запустить полученный файл в эмуляторе GBA (VisualBoy Advance). На экране должна появиться красная точка где-то в районе 10,10. Поздравляю! Только что закончился День 1. © Mike H, пер. Aquila
GBA ASM - День 1: Постигаем ассемблер
Дата публикации 13 июл 2003