Как использовать ассемблер в ардуино

Мне поручили университетский проект по созданию светодиодов, реагирующих на звук и звук, с использованием языка ассемблера. Я уже сделал код C++ в arduino, который использует библиотеку Fastled. Как мне написать рабочий код для этого проекта на ассемблере (не ограничиваясь IDE arduino, но предпочтительнее). Я уже пытался преобразовать свой код в сборку с помощью онлайн-конвертера, но это бесполезно.

, 👍0


4 ответа


0

Вы должны использовать ключевое слово asm, например:

asm("sei \n")

В вашем случае рекомендуется использовать определения, например

#define CLI()          asm("cli \n")
#define noInterrupts() cli()

#define SEI()          asm("sei \n")
#define interrupts()   sei()

Подробнее см. на странице arduino-inline-assembly-tutorial-1.

,

Какую IDE мы должны использовать для этого? Кроме того, эти определения для встроенной сборки? Мы ограничены в том, чтобы основной рабочий код нашей программы был на ассемблере., @COAL

Для этого можно использовать стандартную среду разработки Arduino IDE. Вероятно, вам придется поместить код в функции настройки и цикла. Обратите внимание, однако, что Arduino IDE создает некоторый код вокруг установки и цикла (например, обработка прерываний)., @Michel Keijzers

Подожди здесь. Вы можете использовать #define для функций/методов? Ну, это для меня ново., @Agi Hammerthief


10

Среда Arduino IDE весьма своеобразна. Это не позволит вам работать над проект, в котором нет файла с расширением «.ino». С другой стороны, ему все равно, сколько кода в этом файле, и вы можете держите его счастливым, создав пустой файл .ino. Я рекомендую, однако, что вы поместите хотя бы блок комментариев в этот файл, чтобы сделать вещи меньше путаницы для других людей, которые могли видеть ваш проект. Тогда ты можешь поместите свой ассемблерный код рядом с этим пустым файлом в собственные файлы заканчивается расширением «.S». Эти файлы будут предварительно обработаны перед собирается, поэтому вы можете #include <avr/io.h> и использовать макросы определенные в нем для портов ввода-вывода, битов и т. д.

Проект будет выглядеть следующим образом:

my_project/         # содержащий каталог
├── my_project.ino  # только комментарии, чтобы IDE была счастлива
├── my_project.S    # основной файл сборки
└── some_extras.S   # возможно больше файлов сборки...

Если весь проект представляет собой чистую сборку, один из ваших файлов сборки должен определить символ с именем main, который является точкой входа в программу:

.global main
main:
    ; код начинается здесь

Если вы собираетесь смешивать ассемблер и C++, вы можете определить main() в файле .ino и вызывайте оттуда свои процедуры сборки, которые должен быть объявлен как extern "C":

extern "C" void my_assembly_routine();

int main()
{
    my_assembly_routine();
}

Помните о соглашениях о вызовах при смешивании asm и C++.

Если вы собираетесь использовать базовую библиотеку Arduino, вам следует определить setup() и loop() вместо main(). После этого ядро Arduino предоставить свой собственный main(), который позаботится о его инициализации.

Если вы собираетесь писать в основном на C++, добавляя лишь немного ассемблера тут и там встроенная сборка может быть лучшим вариантом. Cf Мишель Ответ Кейзерса.

,

Проголосовал, много новой информации для меня тоже., @Michel Keijzers


1

Извините.

Основной обучающий эффект этого упражнения — "Не делайте этого". Вы не превзойдете компилятор С++ по производительности (скорости). Но вы столкнетесь с большим количеством ошибок, чем можете себе представить.

Единственной целью языка ручного ассемблера внутри c/c++ является добавление наносекундного времени путем добавления некоторых операторов asm("nop"); для ожидания контролируемого небольшого числа тактов процессора. Примеры @Michel Keijzers уже реализованы. Даже в удобной среде Arduino.

IMO, сложнее выйти за рамки программирования Arduino, перейдя непосредственно к аппаратному уровню микроконтроллера, работая с таймерами, другими компонентами микроконтроллера, регистрами и т. д. напрямую. На С/С++ конечно. Там вы узнаете, что помимо среды Arduino можно сделать гораздо больше.

Или: просмотрите скомпилированные результаты с помощью avr-objdump, чтобы узнать, как эксперты компилируют C++ в машинный код. В конце концов, вы можете заметить, как вы можете помочь оптимизировать компилятор.

,

1. Изучая ассемблирование, вы узнаете намного больше, чем просто «не делайте этого»: вы получаете глубокое понимание того, что делают компилятор и аппаратное обеспечение, и вы узнаете, какие конструкции C/C++ компилируются в эффективный машинный код. Кроме того, вы должны хотя бы немного написать на ассемблере, чтобы по-настоящему оценить работу компилятора (вывод avr-objdump). 2. Нередко avr-gcc производит неоптимальный код, который легко побеждается ручной сборкой. Я предполагаю, что этот вариант gcc не был так точно настроен, как ARM или x86\_64..., @Edgar Bonet

@ Эдгар Боне: Конечно, ты узнаешь гораздо больше. И только после того, как вы узнаете, что вы можете 1. оценить, что компилятор делает для вас 2. интерпретировать его результаты 3. решить, будете ли вы продолжать программирование на ассемблере. Кстати: я пришел из программирования на ассемблере, потому что FORTRAN был не совсем оптимален для небольших машин, и я счастлив, что кто-то изобрел C, а другие создали кросс-компиляторы., @DataFiddler


1

Re: «Основной обучающий эффект этого упражнения — «Не делай этого». Вам не победить компилятор C++..." Я согласен с Эдгаром Боне: (1) Arduino — это обучение, включая изучение программирования на ассемблере, аппаратного обеспечения и т. д. И ... (2) Да, вы можете превзойти компилятор C++, если немного попрактикуетесь. Например, цепочка инструментов GNU может вводить программу C++ и выводить соответствующий ассемблер. Это может быть очень поучительно для изучения ассемблера. Затем вы можете вручную создать любой фрагмент этого кода... сделать его быстрее или меньше. --o-0--

,