|
STM32 Ассемблер. Идеи и приёмы написания, Правила хорошего тона и макросы |
|
|
|
Jan 15 2014, 22:50
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284

|
По ассемблеру для арм документации и разного рода примеров гораздо меньше для С. Начал осваивать и возникли сомнения, правильный ли подход частого использования макросов и где та грань, свыше которой не стоит заморачиваться с написанием кода. В ассемблера я не силён, в основном по-любительски пишу на С. Но вот раз начал осваивать асм, сделал несколько элементарных макросов для битовых операций, настройки и использования портов. Вопрос в том правильно ли это делать и использовать таким образом (когда в коде используются много макросов), или может быть есть более рациональный способ, как лучше писать на асме для арм. Вот примерчик: STM32F100RB. И что конкретно делает команда bfi R1,R2,#$Pin,#4 ? Определение макросов: Код ;-------------------------------------- ;Start_GPIO_Conf $Port,$PinRange - начало настройки порта, где $Port - имя порта (GPIOA,..), $PinRange - верхняя/нижняя тетрада порта (GPIO_CR_H/GPIO_CR_L) macro Start_GPIO_Conf $Port,$PinRange mov32 R0,#$Port ;загружаем в регистр "R0" имя порта (его код) из памяти ldr R1,[R0,#$PinRange];загружаем в регистр "R1" значение по адресу из памяти "R0 + #GPIO_CR_H(0x00)" или "R0 + #GPIO_CR_H(0x04)" mend ;-------------------------------------- ;GPIO_Conf $Pin,$Mode - настройка ножек выбраного порта, где $Pin - номер ножки (CNF_Pin_0,..), $Mode - режим ножки (GPIO_OUT_50_PP,..) macro PinConfig $Pin,$Mode movs R2,#$Mode bfi R1,R2,#$Pin,#4 mend ;-------------------------------------- ;End_GPIO_Conf $Port,$PinRange - конец настройки порта, где $Port - имя порта (GPIOA,..), $PinRange - верхняя/нижняя тетрада порта (GPIO_CR_H/GPIO_CR_L) macro End_GPIO_Conf $Port,$PinRange str R1,[R0,#$PinRange];загружаем в память по адресу "R0 + #GPIO_CR_H(0x00)" или "R0 + #GPIO_CR_H(0x04)" значение "R1" mend ;-------------------------------------- ;SetBit_GPIO $Port,$Pin macro SetBit_GPIO $Port,$Pin mov32 R0,#($Port + GPIO_BSRR) mov32 R1,#$Pin str R1,[R0] mend ;-------------------------------------- ;ResetBit_GPIO $Port,$Pin macro ResetBit_GPIO $Port,$Pin mov32 R0,#($Port + GPIO_BRR) mov32 R1,#$Pin str R1,[R0] mend ;-------------------------------------- Использование в программе: Код ;-------------------------------------- Start_GPIO_Conf GPIOC,GPIO_CR_H PinConfig CNF_Pin_9,GPIO_OUT_50_PP PinConfig CNF_Pin_8,GPIO_OUT_50_PP End_GPIO_Conf GPIOC,GPIO_CR_H ;-------------------------------------- SetBit_GPIO GPIOC,PIN9 SetBit_GPIO GPIOC,PIN8 ;-------------------------------------- Пробный проект в Keil 5 прикреплен:
Сообщение отредактировал allsettingsdone - Jan 15 2014, 22:55
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
Jan 16 2014, 01:58
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Все зависит от того чего вы хотите в итоге. Если вы упражняетесь смысл имеет. Если это коммерческий продукт убежден что не имеет. С темпами развития процессоров сейчас на первый план выход не отдельная производительность одной функции, а удобство поддержки, модификации и расширения программного решения. В том числе и перенос его на другие процессоры и платформы. А для этого чем более абстрактно написан код и чем более читаемо и понятно он написан тем лучше. код из раздела Код a = (!temp) ? 2 : 0; гораздо хуже чем код Код if(temp != 0) a = 2; else a = 0; и второй момент, Код SetBit_GPIO $Port,$Pin macro SetBit_GPIO $Port,$Pin mov32 R0,#($Port + GPIO_BSRR) mov32 R1,#$Pin str R1,[R0] mend каким образом вы будете гарантировать что в ходе выполнения вашей программы к моменту вызова этого макроса у вас свободны R0 и R1? То есть просто по ходу программы написанной на С этот макрос вызывать нельзя. А если вы будете следить за этими регистрами всю программу, то это как раз ярчайший пример АБСОЛЮТНО не поддерживаемого кода. Любое шевеление в будущем чревато багами.
|
|
|
|
|
Jan 16 2014, 05:38
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284

|
Встраивать асемблеровский код в проект на С я не планирую, идея в написании всего проекта на асм, так что я условился приблизительно регистры R0-R3 использовать с оглядкой на то что они будут постоянно меняться, так как задействованы почти во всех макросах. А уже по ходу выполнения программы буду держать в поле зрения другие регистры с ключевой информацией. Вот ещё что интересно: одно и то же действие можно сделать разными командами и бывает не понятно как лучше поступить. Вот например загрузка в регистр адреса из памяти: (кусочек кода из макроса) Код mov32 R0,#$Port или Код ldr R0,=$Port В итоге эти две строчки равнозначны и вот какую из них лучше применять совсем непонятно. Хотелось бы узнать как бы идею и философию подхода к программированию на ассемблере для мк. (может есть годные примеры такого?) Встраивать асемблеровский код в проект на С я не планирую, идея в написании всего проекта на асм, так что я условился приблизительно регистры R0-R3 использовать с оглядкой на то что они будут постоянно меняться, так как задействованы почти во всех макросах. А уже по ходу выполнения программы буду держать в поле зрения другие регистры с ключевой информацией. Вот ещё что интересно: одно и то же действие можно сделать разными командами и бывает не понятно как лучше поступить. Вот например загрузка в регистр адреса памяти: (кусочек кода из макроса) Код mov32 R0,#$Port или Код ldr R0,=$Port В итоге эти две строчки равнозначны и вот какую из них лучше применять совсем непонятно. Или вот ещё Код mov32 R0,#($Port + GPIO_BSRR) Тоже интересно где именно происходит это сложение? Как я понимаю в на эту строчку уйдет далеко не два такта микроконтроллера? Хотелось бы узнать как бы идею и философию подхода к программированию на ассемблере для мк. (может есть годные примеры такого?) PS: с BFI разобрался
Сообщение отредактировал allsettingsdone - Jan 16 2014, 06:27
|
|
|
|
|
Jan 16 2014, 07:10
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Поддерживаю. Весь проект на ассемблере - это долго, опасно, и не эффективно, если конечно вы делаете не новогоднюю гирлянду с 2 режимами мигания.
Убейте книгой того кто вам сказал что крутые железячники все пишут на ассемблере, это было верно для готов 80. Сейчас уже давно и С++ практикуют, потому что стоимость машинного такта неуклонно падает. А требования к скорости и качеству разработки очень быстро растут.
Поглядите новым продуктам ставят сроки жизни и актуальности 4-5 лет. И если вы на ассемблере год будите писать программу, и год ее отлаживать, то через 2-3 оставшихся года при переходе на новый проц, вы что опять 2 года жизни прибора отъедите? Кому нужна такая разработка?
Максимум где допустим ассемблер - это вставки в особо критических местах кода, да и то в 95% случаев оптимизаторы современных языков делают эту работу лучше.
Не ходите валить лес с топором как делали наши деды, уже давно есть бензопилы!
|
|
|
|
|
Jan 16 2014, 07:40
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(allsettingsdone @ Jan 16 2014, 00:50)  Использование в программе: Код ;-------------------------------------- SetBit_GPIO GPIOC,PIN9 SetBit_GPIO GPIOC,PIN8 ;-------------------------------------- Разворачиваем, получаем Код mov32 R0,#(GPIOC + GPIO_BSRR) mov32 R1,#PIN9 str R1,[R0] mov32 R0,#(GPIOC + GPIO_BSRR) mov32 R1,#PIN8 str R1,[R0] Дважды грузится R0 одинаковым значением. И где хваленый выигрыш от Ассемблера? Такого даже самый плохой Си-компилятор себе не позволяет. Не морочьте себе и нам голову, лучше потратьте это время и эти усилия на более глубокое изучение Си или Си с плюсами. Поверьте, это будет гораздо продуктивнее и полезнее. Ассемблер на уровне, достатотчном для анализа листингов и пошаговой отладки вы уже знаете.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 16 2014, 07:50
|

Частый гость
 
Группа: Свой
Сообщений: 115
Регистрация: 6-06-05
Из: Ukraine
Пользователь №: 5 764

|
Топикстартер задал конкретный вопрос в надежде получить от господ ПРОФЕССИОНАЛОВ конкретный ответ и если вы не можете его дать, то наверно лучше помолчать (наболело). Я для ARMов не программирую, но посоветовал бы глянуть книги на эту тему: 1. Joseph Yiu "The Definitive Guide to the ARM Cortex-M0" 2. Joseph Yiu "The Definitive Guide to the ARM Cortex-M3" 3. Vincent Mahout "Assembly Language Programming: ARM Cortex-M3" 4. Muhammad Ali Mazidi "ARM Assembly Language Programming & Architecture" 5. Jonathan Valvano "Embedded Systems: Introduction to Arm® Cortex-M Microcontrollers" Сайт автора книгиВсе эти книги содержат достаточно примеров на асме. Вот ссылка на реальный проект для Cortex-M0, я думаю если поискать, то можно много информации найти. Желаю удачи
|
|
|
|
|
Jan 16 2014, 08:18
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284

|
Как раз читаю одну из этих книг. Что касается С, то на нем я как раз и пишу, но есть мнение что качественно и без извращений, писать на асм может дать выигрыш в прозрачности кода и более логически правильному её написанию и именно к микроконтроллерам это очень даже применимо. Я думаю что современный компилятор таки может гораздо лучше человека составить асм код, но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С.
Сообщение отредактировал allsettingsdone - Jan 16 2014, 08:24
|
|
|
|
|
Jan 16 2014, 09:57
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С. Вы всегда можете открыть листинги и посмотреть что сделал компилятор и подправить.
|
|
|
|
|
Jan 16 2014, 10:56
|
Участник

Группа: Участник
Сообщений: 32
Регистрация: 22-01-13
Пользователь №: 75 284

|
Ладно, а что по поводу таких вещей: Код mov32 R0,#($Port + GPIO_BSRR) Интересно, где именно происходит сложение "$Port + GPIO_BSRR" в данном случае $Port = 0x40001800, а GPIO_BSRR = 0x10. Для такой операции тоже ведь нужно использовать регистры, я пытался проследить этот момент, но именного таких чисел не увидел. И где вообще хранится константы когда мы используем их в виде "mov R0,#4" - вот число 4 здесь, процессор же должен от куда нибудь его взять? Откуда именно (если из ПЗУ, то как узнать по какому адресу компилятор что,где ложит)? Цитата(Golikov A. @ Jan 16 2014, 12:23)  ассемблер очевиднее С, только для ОЧЕНЬ маленьких программок из раздела мигаем лампочкой. Да и то С тут очевиднее... Любую программу же можно разбить на отдельные блоки/функции/файлы отвечающие за что-то одно. И можно будет во всем разобраться.
Сообщение отредактировал allsettingsdone - Jan 16 2014, 10:53
|
|
|
|
|
Jan 16 2014, 11:08
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(allsettingsdone @ Jan 16 2014, 14:18)  Как раз читаю одну из этих книг. Что касается С, то на нем я как раз и пишу, но есть мнение что качественно и без извращений, писать на асм может дать выигрыш в прозрачности кода и более логически правильному её написанию и именно к микроконтроллерам это очень даже применимо. Как правило, наоборот - чем код объёмнее - тем он менее прозрачен, а на асме код всяко будет ОБЪЁМНЕЕ  Цитата(allsettingsdone @ Jan 16 2014, 14:18)  Я думаю что современный компилятор таки может гораздо лучше человека составить асм код, Что-то очень часто приходится слышать это заблуждение.... По-моему пошло из рекламных буклетов си-компиляторов и к реалиям не имеет никакого отношения. Не встречал ещё ни одного компилятора, способного написать на асме лучше меня  Причём бывает что это соотношение в разы. Даже со всеми оптимизациями. Даже не очень хорошего знания ассемблера достаточно чтобы написать оптимальнее си-компилёра. Хотя я совсем не агитирую писать на чистом асм - сейчас это затея отдаёт мазохизмом. Сейчас асм только для отдельных функций. Цитата(allsettingsdone @ Jan 16 2014, 14:18)  но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С. Достаточно периодически заглядывать в листинги. И через некоторое время вам достаточно будет только бросить взгляд на эту строчку, чтобы примерно прикинуть, что получится на асме  Цитата(scifi @ Jan 16 2014, 17:05)  Настоящие мущщины кодят прямо в хексе :-)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|