allsettingsdone 0 15 января, 2014 Опубликовано 15 января, 2014 (изменено) · Жалоба По ассемблеру для арм документации и разного рода примеров гораздо меньше для С. Начал осваивать и возникли сомнения, правильный ли подход частого использования макросов и где та грань, свыше которой не стоит заморачиваться с написанием кода. В ассемблера я не силён, в основном по-любительски пишу на С. Но вот раз начал осваивать асм, сделал несколько элементарных макросов для битовых операций, настройки и использования портов. Вопрос в том правильно ли это делать и использовать таким образом (когда в коде используются много макросов), или может быть есть более рациональный способ, как лучше писать на асме для арм. Вот примерчик: 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 прикреплен: test11_ASM.7z Изменено 15 января, 2014 пользователем allsettingsdone Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Все зависит от того чего вы хотите в итоге. Если вы упражняетесь смысл имеет. Если это коммерческий продукт убежден что не имеет. С темпами развития процессоров сейчас на первый план выход не отдельная производительность одной функции, а удобство поддержки, модификации и расширения программного решения. В том числе и перенос его на другие процессоры и платформы. А для этого чем более абстрактно написан код и чем более читаемо и понятно он написан тем лучше. код из раздела 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? То есть просто по ходу программы написанной на С этот макрос вызывать нельзя. А если вы будете следить за этими регистрами всю программу, то это как раз ярчайший пример АБСОЛЮТНО не поддерживаемого кода. Любое шевеление в будущем чревато багами. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
allsettingsdone 0 16 января, 2014 Опубликовано 16 января, 2014 (изменено) · Жалоба Встраивать асемблеровский код в проект на С я не планирую, идея в написании всего проекта на асм, так что я условился приблизительно регистры R0-R3 использовать с оглядкой на то что они будут постоянно меняться, так как задействованы почти во всех макросах. А уже по ходу выполнения программы буду держать в поле зрения другие регистры с ключевой информацией. Вот ещё что интересно: одно и то же действие можно сделать разными командами и бывает не понятно как лучше поступить. Вот например загрузка в регистр адреса из памяти: (кусочек кода из макроса) mov32 R0,#$Port или ldr R0,=$Port В итоге эти две строчки равнозначны и вот какую из них лучше применять совсем непонятно. Хотелось бы узнать как бы идею и философию подхода к программированию на ассемблере для мк. (может есть годные примеры такого?) Встраивать асемблеровский код в проект на С я не планирую, идея в написании всего проекта на асм, так что я условился приблизительно регистры R0-R3 использовать с оглядкой на то что они будут постоянно меняться, так как задействованы почти во всех макросах. А уже по ходу выполнения программы буду держать в поле зрения другие регистры с ключевой информацией. Вот ещё что интересно: одно и то же действие можно сделать разными командами и бывает не понятно как лучше поступить. Вот например загрузка в регистр адреса памяти: (кусочек кода из макроса) mov32 R0,#$Port или ldr R0,=$Port В итоге эти две строчки равнозначны и вот какую из них лучше применять совсем непонятно. Или вот ещё mov32 R0,#($Port + GPIO_BSRR) Тоже интересно где именно происходит это сложение? Как я понимаю в на эту строчку уйдет далеко не два такта микроконтроллера? Хотелось бы узнать как бы идею и философию подхода к программированию на ассемблере для мк. (может есть годные примеры такого?) PS: с BFI разобрался Изменено 16 января, 2014 пользователем allsettingsdone Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Встраивать асемблеровский код в проект на С я не планирую, идея в написании всего проекта на асм Ну и зря. Это просто борьба с ветряными мельницами какая-то. Она имеет право на жизнь, конечно, но лучше потратьте своё время на что-нибудь более полезное и интересное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Поддерживаю. Весь проект на ассемблере - это долго, опасно, и не эффективно, если конечно вы делаете не новогоднюю гирлянду с 2 режимами мигания. Убейте книгой того кто вам сказал что крутые железячники все пишут на ассемблере, это было верно для готов 80. Сейчас уже давно и С++ практикуют, потому что стоимость машинного такта неуклонно падает. А требования к скорости и качеству разработки очень быстро растут. Поглядите новым продуктам ставят сроки жизни и актуальности 4-5 лет. И если вы на ассемблере год будите писать программу, и год ее отлаживать, то через 2-3 оставшихся года при переходе на новый проц, вы что опять 2 года жизни прибора отъедите? Кому нужна такая разработка? Максимум где допустим ассемблер - это вставки в особо критических местах кода, да и то в 95% случаев оптимизаторы современных языков делают эту работу лучше. Не ходите валить лес с топором как делали наши деды, уже давно есть бензопилы! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Использование в программе: ;-------------------------------------- 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 одинаковым значением. И где хваленый выигрыш от Ассемблера? Такого даже самый плохой Си-компилятор себе не позволяет. Не морочьте себе и нам голову, лучше потратьте это время и эти усилия на более глубокое изучение Си или Си с плюсами. Поверьте, это будет гораздо продуктивнее и полезнее. Ассемблер на уровне, достатотчном для анализа листингов и пошаговой отладки вы уже знаете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ozelot 9 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Топикстартер задал конкретный вопрос в надежде получить от господ ПРОФЕССИОНАЛОВ конкретный ответ и если вы не можете его дать, то наверно лучше помолчать (наболело). Я для 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, я думаю если поискать, то можно много информации найти. Желаю удачи :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
allsettingsdone 0 16 января, 2014 Опубликовано 16 января, 2014 (изменено) · Жалоба Как раз читаю одну из этих книг. Что касается С, то на нем я как раз и пишу, но есть мнение что качественно и без извращений, писать на асм может дать выигрыш в прозрачности кода и более логически правильному её написанию и именно к микроконтроллерам это очень даже применимо. Я думаю что современный компилятор таки может гораздо лучше человека составить асм код, но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С. Изменено 16 января, 2014 пользователем allsettingsdone Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Я думаю что современный компилятор таки может гораздо лучше человека составить асм код, но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С. На самом деле всё-таки почти всегда очевидно, что он там нагенерит. А если не очевидно, то заглянуть в дизассемблер совсем не сложно. Ну и погоня за тактами - это ложная и вредная цель. Реально такая задача возникает крайне редко, и решается она небольшой ассемблерной вставкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость MALLOY2 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С. Вы всегда можете открыть листинги и посмотреть что сделал компилятор и подправить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба ассемблер очевиднее С, только для ОЧЕНЬ маленьких программок из раздела мигаем лампочкой. Да и то С тут очевиднее... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
allsettingsdone 0 16 января, 2014 Опубликовано 16 января, 2014 (изменено) · Жалоба Ладно, а что по поводу таких вещей: mov32 R0,#($Port + GPIO_BSRR) Интересно, где именно происходит сложение "$Port + GPIO_BSRR" в данном случае $Port = 0x40001800, а GPIO_BSRR = 0x10. Для такой операции тоже ведь нужно использовать регистры, я пытался проследить этот момент, но именного таких чисел не увидел. И где вообще хранится константы когда мы используем их в виде "mov R0,#4" - вот число 4 здесь, процессор же должен от куда нибудь его взять? Откуда именно (если из ПЗУ, то как узнать по какому адресу компилятор что,где ложит)? ассемблер очевиднее С, только для ОЧЕНЬ маленьких программок из раздела мигаем лампочкой. Да и то С тут очевиднее... Любую программу же можно разбить на отдельные блоки/функции/файлы отвечающие за что-то одно. И можно будет во всем разобраться. Изменено 16 января, 2014 пользователем allsettingsdone Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Любую программу же можно разбить на отдельные блоки/функции/файлы отвечающие за что-то одно. И можно будет во всем разобраться. Настоящие мущщины кодят прямо в хексе :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба Как раз читаю одну из этих книг. Что касается С, то на нем я как раз и пишу, но есть мнение что качественно и без извращений, писать на асм может дать выигрыш в прозрачности кода и более логически правильному её написанию и именно к микроконтроллерам это очень даже применимо. Как правило, наоборот - чем код объёмнее - тем он менее прозрачен, а на асме код всяко будет ОБЪЁМНЕЕ :) Я думаю что современный компилятор таки может гораздо лучше человека составить асм код, Что-то очень часто приходится слышать это заблуждение.... По-моему пошло из рекламных буклетов си-компиляторов и к реалиям не имеет никакого отношения. Не встречал ещё ни одного компилятора, способного написать на асме лучше меня :) Причём бывает что это соотношение в разы. Даже со всеми оптимизациями. Даже не очень хорошего знания ассемблера достаточно чтобы написать оптимальнее си-компилёра. Хотя я совсем не агитирую писать на чистом асм - сейчас это затея отдаёт мазохизмом. Сейчас асм только для отдельных функций. но когда пишешь на С, то не всегда очевидно какое огромное кол-во операций может повлечь за собой та или иная простенькая строчка на С. Достаточно периодически заглядывать в листинги. И через некоторое время вам достаточно будет только бросить взгляд на эту строчку, чтобы примерно прикинуть, что получится на асме :) Настоящие мущщины кодят прямо в хексе :-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 16 января, 2014 Опубликовано 16 января, 2014 · Жалоба 1. Для некоторых процессоров ассемблер достаточно простой и наглядный. ARM ассемблер этими свойствами очевидно не обладает. Это мнение разработчиков компиляторов, ссылаясь на слова Тревора. 2. Написать несложную программу на простом ассемблере, с использованием макросов действительно несложно. Но Вам сказали об переносимости и поддерживаемости (сопровождении). А здесь ассемблер даже не мина а огромная бомба. Для того, чтобы Вы сами приняли правильное решение предлагаю Вам несложный эксперимент. Напишите проект на ASM. Сделайте выдержку 1-2 месяца. Внесите в него изменения. Только изменения не сразу продумайте, а попросите кого-нибудь со стороны, чтобы он придумал Вам изменения. Ну и отладьте. Я думаю, больше у Вас вопросов к форуму не будет. PS: Я писал значительные проекты на ASM. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться