Я пытаюсь написать очень простой кросс-компилятор для малины Pi B + Version для создания простых простых металлических программ. Мой компилятор способен переводить простые команды в соответствующую инструкцию машинного языка, используя таблицу набора инструкций ARM.ARMv6 Branch in Bare Metal Programming (Raspberry Pi B +)
Включение светодиодов (ориентируется на курс выпечки, http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/) работает отлично.
Но теперь я хочу сделать некоторые инструкции ветвления, и это, где ничто не похоже на работу больше:
Во-первых, я хотел бы перейти к абсолютному адресат, не относительные ветви с помощью B/BL инструкция.
Чтобы проверить ветку, я использую следующий код разобранном (разобран с помощью Хоппер дизассемблер V3 тестовой версии), которым включается светодиодный индикатор, связанный с GPIO 16 and22:
00000000 mov r0, #0x20000000 ;Load the GPIO Base Address into R0
00000004 orr r0, r0, #0x200000
00000008 mov r1, #0x40 ;Load the Set Function Mask (for GPIO 22) into r1
0000000c str r1, [r0, #0x8] ;Store the Set Function Mask into the GPFSEL2
00000010 mov r1, #0x400000 ;Move the Set Output Mask (for GPIO 22) into r1
00000014 str r1, [r0, #0x1c] ;Store the Set Output Mask into GPSET0
00000018 mov r0, #0x20000000 ;Load the GPIO Base Address into R0
0000001c orr r0, r0, #0x200000
00000020 mov r1, #0x40000 ;Load the Set Function Mask (for GPIO 16) into r1
00000024 str r1, [r0, #0x4] ;Store the Set Function Mask into the GPFSEL2
00000028 mov r1, #0x10000 ;Move the Set Output Mask (for GPIO 16) into r1
0000002c str r1, [r0, #0x1c] ;Store the Set Output Mask into GPSET0
00000030 b 0x30 ;Infinity Loop to keep the processor up
Теперь я хочу добавьте ветвь в начало кода, чтобы пропустить первый раздел, так что активируется только второй светодиод.
Я пробовал так:
mov r15, #0x1c
но единственный эффект, что оба светодиода оставаться темным.
Моя вторая попытка как то:
mov r2, #0x20
bx r2
Но что ни работ.
Так что мой вопрос:
- Как выполнить такую ветку?
- Я использую адреса правильно?
Это может сделать интересное упражнение по обучению, gcc имеет опцию '-ffreestanding' для создания кода, который не зависит от каких-либо библиотек. Я предполагаю, что ассемблер GNU может собрать ARM asm в плоский двоичный файл, если вы его попросите, поэтому вы можете использовать его для записи кода запуска, который устанавливает для запуска ваших функций вывода компилятора. Насколько я понимаю, это как раз то, как ядро Linux построено: в основном C с некоторым asm для установки, и процесс сборки, который делает образ ядра вместо исполняемого файла ELF. –