Перейти к содержанию
    

STM32 Ассемблер. Идеи и приёмы написания

ЗЫ. Мы все стремимся, испольуя более высокоуровневые языки, облегчить себе жизнь, потому что у заказчиков требования тоже растут неплохо. Если 5-10 лет назад им было достаточно настройки устройства через простейшую менюшку с кнопками вниз\вверх, то теперь подавай удаленный доступ, желательно через инет, обновление прошивки по 1 тычку кнопки и т.д. Идите в ногу со временем, а не занимайтесь глупостями в виде чистого асма!

С такими запросами и Си - совсем не панацея. Там уже это называется "экосистема", наверное. В любом случае, асм совсем не в тему, конечно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо какое-то пространство обсуждения принять. Потому что, скажем, в случае JIT-компиляции, - это нарушение закона сохранения или расширение множества свойств наблюдаемой системы? А то мы так быстро заблудимся :)

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разворачиваем, получаем

        mov32            R0,#(GPIOC + GPIO_BSRR)
         mov32            R1,#PIN9
         str            R1,[R0]
         mov32            R0,#(GPIOC + GPIO_BSRR)
         mov32            R1,#PIN8
         str            R1,[R0]

Дважды грузится R0 одинаковым значением. И где хваленый выигрыш от Ассемблера? Такого даже самый плохой Си-компилятор себе не позволяет. Не морочьте себе и нам голову, лучше потратьте это время и эти усилия на более глубокое изучение Си или Си с плюсами. Поверьте, это будет гораздо продуктивнее и полезнее. Ассемблер на уровне, достатотчном для анализа листингов и пошаговой отладки вы уже знаете

 

Постоянная бесполезная перезагрузка регистров одними и теми же значениями -- любимое занятие GCC. Вообще, высокая эффективность компиляторов -- это сказки. Даже лучшие из них дают не такой уж хороший код. Другое дело, что далеко не всегда имеет смысл писать вручную на ассемблере -- обычно производительность и компактность не являются главными критериями, хотя иногда они и важны. В общем, надо подходить к этому без фанатизма.

 

Сравнительная скорость разработки программы на ассемблере и языке высокого уровня очень сильно зависит от задачи и от системы команд. Если там сплошные опросы, манипуляции с битами и переходы по условиям, разница весьма невелика. А вот если сложные расчёты -- очень заметная (то, что на ЯВУ пишется за 5-10 мин, на ассемблере можно и час, и два делать).

 

Скорость отладки больше зависит от используемого языка; с числом строк программы она на самом деле связана лишь в том случае, если сравниваются программы на одном и том же языке. Между Си и ассемблером по числу ошибок особой разницы нет: и там, и там крайне легко допустить какие-нибудь ляпы, но на Си их искать часто бывает сложней (там куда более заковыристые проблемы могут быть по сравнению с ассемблером, где, пожалуй, основной источник ошибок -- неверный номер регистра). Вот если сравнивать ассемблер и Си с Адой или хотя бы Паскалем -- разница в числе ошибок будет в разы.

 

Но моя убежденность в том что сишный код с одной платформы на другую еще можно перенести, а асмовый - практически всегда беда...

 

Что значит с платформы на платформу? Если речь о разных архитектурах процессоров (скажем, с IA-32 на ARM или наоборот), то код на любом языке высокого уровня можно перенести, если есть компилятор, ну а на ассемблере нельзя -- ведь он прямо отражает архитектуру машины. Но если говорить о процессорах одной архитектуры, тогда проблем нет. Скажем, если надо перенести программу с какого-нибудь STM32 на какой-нибудь NXPшный микроконтроллер (и тот, и другой принадлежат к архитектуре ARM), то что на ассемблере, что на Си придётся переписывать код, относящийся к инициализации синхронизации, работе с периферией и т.д. -- поскольку эти вещи у разных МК различаются. Однако код, собственно решающий задачу, остаётся неизменным. Конечно, это при условии, если он написан достаточно грамотно -- но то же самое относится и к коду на ЯВУ (если ты в каждой функции напихал код, зависящий от конкретной модели МК, то и переделывать каждую функцию придётся).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Между Си и ассемблером по числу ошибок особой разницы нет: и там, и там крайне легко допустить какие-нибудь ляпы, но на Си их искать часто бывает сложней (там куда более заковыристые проблемы могут быть по сравнению с ассемблером

 

Сегодня такие грабли выловил....ужас. В общем, додумался я описать структуру в теле функции. Переменная локальная, какая разница вроде бы... оказалось что в elf при этом что-то приписывается такое, что не все его потом понимают. Нужен был протеус, а он не грузил файл... только описание структуры вынес - заработало.

код на любом языке высокого уровня можно перенести, если есть компилятор, ну а на ассемблере нельзя

Псевдокод - можно! Если макросредства не меняются.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

напишите виндус ан ассемблере, а потом рассказывайте что С код труднее отлаживать...

 

описали структуру не так... так в ассемблере структуры вообще нет.

А реюзинг? А Класс с++?

 

С++ дает огромные преимущества в повторном использовании кода, правда конечно если вы не балуетесь перегрузкой сложения вычитанием, а вычитания сложением.

 

С, С++, ява, асемблер - это инструменты. Новые не появлялись бы если прошлые всех устраивали, но так же старые не оставались в строю, если бы новые делали все что надо. Правда как всегда по середине, но смещена в сторону частоты использования.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Псевдокод - можно! Если макросредства не меняются.

 

Псевдокод будет уступать по эффективности родному ассемблеру конкретной архитектуры, поскольку, используя этот самый родной ассемблер, можно эффективно использовать особенности данной архитектуры, а псевдокод (если я правильно понял, что Вы имеете в виду) будет сродни языку высокого уровня -- представлять некие машинно-независимые абстракции, которые нужно транслировать в машинный код. Скажем, такая операция, как пересылка или сравнение последовательности байтов в двух областях памяти, на одной архитектуре потребует целой подпрограммы, на другой -- 2-3 инструкций, на третьей -- вообще одной инструкции, но при этом будут различаться требования к размещению адресов областей и т.д. Сделать эффективную трансляцию подобного с помощью макросов под любые архитектуры не получится -- всегда будут всплывать особенности и ограничения конкретных архитектур (скажем, на IA-32 эта задача формально решается одной инструкцией с префиксом повторения, однако исходные данные должны быть загружены в строго определённые регистры; на ARM требуется несколько команд, но зато можно пользоваться любыми регистрами, в Системе 360 и её потомках, включая современные мэйнфреймы, есть две инструкции для решения каждой из этих задач с разным способом указания областей памяти, и в разных случаях надо использовать одну из них, на VAX это решается одной инструкцией без каких-то особых ограничений и т.д.). Ну а поскольку одна из основных причин использования ассемблера заключается в получении большей эффективности, чем при кодировании той же задачи на каком-то ЯВУ, жертвовать ею ради такой "макропереносимости" смысла нет.

 

А вот в рамках одной архитектуры макросы очень сильно могут помочь. У меня, например, есть набор своих макросов, которые помогают эффективнее использовать язык ассемблера в зависимости от того, какой набор команд -- Thumb или Thumb-2 -- доступен, а также что из себя представляют операнды. Т.е. программа пишется частью обычными инструкциями (там, где разницы нет), частью такими макросами, а они внутри себя используют условную трансляцию, чтобы сформировать наиболее подходящую последовательность инструкций. Например, мой макрос MOVC загружает в регистр константу, при этом он может превратиться в инструкцию movs, movw или ldr в зависимости от значения константы и доступной системы команд. Ну а в тех случаях, когда макросы помочь не могут (из-за того, что задача уж очень специализированная), но нужно обеспечить переносимость под разные версии архитектуры, я уже сам явным образом использую условную трансляцию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Псевдокод будет уступать по эффективности родному ассемблеру конкретной архитектуры, поскольку, используя этот самый родной ассемблер, можно эффективно использовать особенности данной архитектуры, а псевдокод (если я правильно понял, что Вы имеете в виду) будет сродни языку высокого уровня -- представлять некие машинно-независимые абстракции, которые нужно транслировать в машинный код.

 

Ну например...

Сделали конструкцию, которая является нечто похожим на

typedef void (*process_t)(void);
const process_t flowchart[]={&proc1,&proc2,&proc3};

void steps(uint num)
{
  flowchart[num]();
}

Причем, зная что мы делаем таблицу указателей на функции не больше 256 элементов, иначе крыша счастливого программера вспухнет :)

можем ввести псевдокод например 16-битный <0xFF><адрес-в-таблице-функций> как безусловное исполнение, ну там... несколько вариантов условных, объяснить кто куда данные поставляет. Это все в пределах 16 бит можно.

 

и цикл, который такую таблицу схавает, уже описать в виде макроса

 

Заметьте, ничего святого :) никак микро-интерпретатор не претендует на роль глобальной системы. просто вкрапления. Не нравится такая система? Тут же конструируем и применяем другую. Регистров в контроллере многовато? ок, можно параллелить процессы с меньшим числом регистров.

 

портирование сводится ессно к реализации зоопарка таких штук.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Добрый день

Что-бы не плодить темы. Помогите стартануть проект на asm в iar.

                  NAME    test
                  PUBLIC  __iar_program_start
                  SECTION .intvec : CODE (2)
                  CODE 
#include "startup_stm32f072.s"  
                  SECTION .intvec : CODE (2)
                  CODE
                  SECTION .text : CODE (2)
                  CODE        

__iar_program_start        
       B       init    ;main

init:
main    NOP
          B main

          END 

 

Этот простейший проект не компилится, выдаются ошибки:

Warning[25]: Label 'Reset_Handler' is defined pubweak in a section implicitly declared root E:\IAR_ARM\startup_stm32f072.s 121

Warning[18]: END of program while in include file E:\IAR_ARM\startup_stm32f072.s 345

Error[50]: Undefined symbol:'__iar_program_start' E:\IAR_ARM\startup_stm32f072.s 124

 

Может кто-нибудь помочь примером любого многофайлового asm-овского проекта для IAR для STM32? (интересует собственено начальная часть , где подключаются процедуры из других файлов, декларируются переменные, вектора прерываний и т.д.)

И еще - как задать расположение переменных в RAM, констант в eeprom и flash?

Заранее спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возьмите любой cstartup.asm (или как он там называется) из любого примера IAR для вашего ядра.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...