GBA ASM - День 1: Постигаем ассемблер

Дата публикации 13 июл 2003

GBA ASM - День 1: Постигаем ассемблер — Архив WASM.RU

Вы можете спросить, будем ли мы использовать тот же ассемблер, который идёт вместе с GCC. Короткий ответ: НЕТ. Развёрнутый ответ: мы будем использовать ассемблер Goldroad, который можно найти на его сайте или скачать здесь. Я использую версию 1.6F. Вам следует скачать самую последнюю версию ассемблера и распаковать её куда-нибудь, так чтобы в пути не было пробелов. Если в пути нет пробелов - это всегда существенно облегчает жизнь.

Оки, вы распаковали ассемблер туда, куда хотели. У меня есть файл, который может вам изрядно помочь. Это screen.h из туториала Pern'а, который я вручную сконвертировал в синтаксис ассемблера Goldroad. Скачайте его здесь и поместите в ту же директорию, где находится Goldroad.exe.

Теперь вы наверняка захотите проверить, как он работает. Но для начала вам нужен эмулятор. Идите и найдите VisualboyAdvance, так как я на 100% уверен, что он понимает командную строку. Чтобы проверить, как он работает, создайте файл first.asm, скопируйте в него нижеследующий исходник и поместите в ту же директорию, где находится ассемблер.

Код (Text):
  1.  
  2. ; начинайте копировать отсюда
  3.  
  4. @include screen.h
  5. @textarea
  6.  
  7. ldr r1,=REG_DISPCNT
  8. ldr r2,=(BG2_ENABLE|MODE_3)
  9. str r2,[r1]
  10. ldr r1,=0x0FF
  11. ldr r2,=vram+2410
  12. str r1,[r2]
  13. label1
  14. B label1
  15.  
  16. @pool
  17. @endarea
  18.  
  19. ; заканчивайте копировать здесь

Альтернативный код на C будет примерно следующим:

Код (Text):
  1.  
  2. int main()
  3. {
  4. SetMode(MODE_3|BG2_ENABLE);
  5. vram[2410] = 0x0FF;
  6. while(1)
  7. {}
  8. }

Тем не менее, как вы вероятно знаете, скомпилированный C-код будет ОГРОМНЫМ. Только ассемблер может дать вам маленькие бинарники. Давайте проанализируем исходник строка за строкой.

Код (Text):
  1.  
  2. @include screen.h

Эта строка делает то же самое, что и выражение #include в C.

Код (Text):
  1.  
  2. @textarea

Эта строка просто определяет, где начинается код.

Код (Text):
  1.  
  2. 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):
  1.  
  2. ldr r1,=REG_DISPCNT
  3.  
  4.  * Это инструкция LDR.
  5.  
  6.         * Первым параметром в нашем случае является регистр r1.
  7.  
  8.         * REG_DISPCNT задан в screen.h и определяет местонахождение памяти
  9.            управления экраном.

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

Код (Text):
  1.  
  2. ldr r2,=(BG2_ENABLE|MODE_3)

Здесь то же самое, что и в предыдщущей строке, только на этот раз вторым операндом являются два сORенных значения (оператор '|'). BG2_ENABLE и MODE_3 заданы в screen.h и будучи сORенными дают значение 0x0403. Это значение помещается в регистр r2.

Код (Text):
  1.  
  2. str r2,[r1]

Вау, наша вторая инструкция, инструкция STR помещает значение первого регистра в ячейку памяти, задаваемую вторым операндом. STR расшифровывается как STore Register (сохранить регистр). В данном случае квадратные скобки [] говорят, что регистр используется как указатель. Знаете что? Эти три инструкции делают то, что в C для нас делает SetMode(MODE_3|BG2_ENABLE). Это переводит экран в битмэп-режим номер три (3).

Код (Text):
  1.  
  2. ldr r1,=0x0FF

Сейчас вы должны это понять - это загружает в r1 0x0FF (255).

Код (Text):
  1.  
  2. ldr r2,=vram+2410

Вы должны понять и этом, за исключением того, что я сейчас объясню. Для начала, просто чтобы вы знали, vram также задаётся в screen.h, и это память, в которую вам понадобится писать, чтобы вывести что-нибудь на экран. vram определяется как 0x06000000.

Теперь наша инструкция прибавляет 2410 к значению vram, загружая значение в r2. Почему? Чтобы поместить значение цвета вам нужно задать x и y, верно? Поэтому вот формула для 3-его режима:

Код (Text):
  1.  
  2.     y * 240 + x

Соответственно наша инструкция задаёт позицию x=10, y=10. Более того, 0x0FF, который мы ранее поместили в r1, будет означать ярко-красный цвет, когда мы поместитм точку на экран.

Код (Text):
  1.  
  2. str r1,[r2]

Снова инструкция str, только в этом раз мы помещаем содержимое регистра r1 в ячейку памяти, на которую указывает r2. В данном случае r2 указывает на экранную координату 10,10, а r1 - это ярко-красный цвет. Таким образом, сохранение ярко-красного цвета в экранную память в позиции 10,10... Позже я дам вам увидеть результат. Но пока ещё немного кода.

Код (Text):
  1.  
  2. label1

Задаёт метку, к которой вы можете перейти подобно тому, как работает команда goto в BASIC.

Код (Text):
  1.  
  2. b label1

Эквивалентно 'Goto label1' в BASIC'е. Эти две строки создают бесконечный цикл. Инструкция B работает подобно инструкции Jxxx в x86-ассемблере, она передаёт управление в зависимости от результата предыдущих операций, подробнее об этом будет написано дальше.

Код (Text):
  1.  
  2. @pool

Даёт ассемблеру место, куда можно поместить некоторые из чисел, которые мы задавали и использовали. АБСОЛЮТНО НЕОБХОДИМО.

Код (Text):
  1.  
  2. @endarea

Говорит ассемблеру, что секция кода закончена.

Эй, мы только что закончили с нашей первой программой под GBA на ассемблере!

Компилирование нашего исходника

Я предполагаю, что вы работаете в Windows, да и один совет - ПОСТАВЬТЕ XP! (Второй совет от переводчика - СНЕСИТЕ XP!)

Наберите 'goldroad first.asm' в директории, где находится Goldroad Assembler и нажмите ввод.

Если вы увидели какие-нибудь сообщения об ошибках, попробуйте снова, убедитесь, что задали команду верно.

Если вы увидели "Assembled successfully" или что-нибудь вроде этого, поздравляю!

Если всё прошло как надо, то в папке Goldroad'а должен появиться файл first.gba.

Теперь осталось запустить полученный файл в эмуляторе GBA (VisualBoy Advance). На экране должна появиться красная точка где-то в районе 10,10. Поздравляю! Только что закончился День 1. © Mike H, пер. Aquila


0 1.762
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532