Проект замигайки на СТМ? Ну это классика. Могу сказать, что получится такой же самый результат, поскольку у АРМ нет разницы между ОЗУ и регистрами периферии в плане работы инструкций с ними.
Вот пример для BluePill. Настройку пинов и тактирования опускаю, чтобы не мешались. Чисто переключение PС13 (светик) и задержка Delay.
Код:
void Delay(volatile uint32_t count)
{
while(--count);
}
int main()
{
while(true)
{
GPIOC->BSRR = GPIO_BSRR_BS13; // PC13 = high
Delay(1000);
GPIOC->BSRR = GPIO_BSRR_BR13; // PC13 = low
Delay(2500);
}
}
При включении -O3 компилируется так:
Код:
20000150: mov.w r0, #8192 ; в r0 записывается 0x2000, (эквивалент GPIO_BSRR_BS13 )
20000154: mov.w r1, #536870912 ; в r1 записывается 0x20000000 (эквивалент GPIO_BSRR_BR13)
20000158: ldr r2, [pc, #20] ; (20000170 <main+0x20>) в r2 заносится базовый адрес регистров GPIOC
2000015a: mov.w r3, #1000 ; в r3 заносится задержка 1000
2000015e: str r0, [r2, #16] ; ---- PC13 = high! -----
20000160: subs r3, #1 ; Отсчет задержки, уменьшая на 1 содержимое r3, с воздействием на флаги состояния
20000162: bne.n 20000160 <main+0x10> ; если в r3 не 0, повторить предыдущую инструкцию
20000164: movw r3, #2500 ; 0x9c4 ; в r3 заносится задержка 2500
20000168: 6111 str r1, [r2, #16] ; ---- PC13 = low! ----
2000016a: 3b01 subs r3, #1 ; Отсчет задержки, уменьшая на 1 содержимое r3
2000016c: bne.n 2000016a <main+0x1a> ; если в r3 не 0, повторить
2000016e: b.n 2000015a <main+0xa> ; перейти на начало цикла
20000170: .word 0x40011000
Ядро АРМ всю арифметическую и логическую работу проводит во внутренних регистрах ядра. Их 16 штук, часть из них имеет фиксированное назначение (счетчик программ pc, указатель стека sp, линк-регистр lr). Для операций используется в основном первые 8 регистров (r0 - r7). Старшие регистры r8 - r12 задействуются только 32-битным вариантом инструкций. Самих инструкций в младшем АРМ наборе не сильно много (хотя в CM7 - в несколько раз больше, порядка 200 штук, если не изменяет память), но каждая инструкция имеет несколько вариантов. Одни и те же инструкции могут быть представлены как в 16-битной, так и в 32-битной ширине, могут иметь дополнительные суффиксы, воздействующие на флаги состояния операции. Один из операндов инструкции может содержать дополнительную составную инструкцию.
В общем, обычный базовый код на асме написать можно. А вот эффективный, такой чтобы прям ну ваще, да еще в масштабах всей программы, а не локализованного участка - вот это уже вопрос выше среднего уровня подготовки. В дополнение к тому, что прорабатываешь логику программы, приходится еще постоянно следить за низкоуровневой логикой применения инструкций. Пока там наработаешь все эти макроблоки и ассемблерные библиотеки, на это тоже будет уходить дополнительное время.
Так что нет, извините, но написание программ целиком на ассемблере, по крайней мере это не мой выбор

Кто-то в соседней теме сказал, что дескать средней руки ассемблерщик напишет программу лучше, чем компилятор при наивысшей оптимизации. Ну-ну, пускать слова на ветер может любой. Но пусть он вначале попробует написать хотябы то, что генерит компилятор без оптимизации. В масштабах целой программы, а не отдельного кусочка, разумеется.
Я раньше тоже писал на ассемблере, и довольно долго. Но чем тяжелее становились проекты, тем сильнее росло желание спрыгнуть с ассемблера. Впрочем, повторюсь, я никого ни к чему не призываю, я просто рассказываю свой опыт. А на чем писать - дело лично каждого.