Часть кода на ядре ATmega, которая выполняет setup () и loop (), выглядит следующим образом:
#include <Arduino.h>
int main(void)
{
init();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
Довольно просто, но есть издержки для serialEventRun (); там.
Давайте сравним два простых наброска:
void setup()
{
}
volatile uint8_t x;
void loop()
{
x = 1;
}
и
void setup()
{
}
volatile uint8_t x;
void loop()
{
while(true)
{
x = 1;
}
}
Значение x и volatile просто для гарантии того, что оно не оптимизировано.
В произведенном ASM вы получите разные результаты:
Вы можете видеть, что while (true) просто выполняет rjmp (относительный переход) назад для нескольких инструкций, тогда как loop () выполняет вычитание, сравнение и вызов. Это 4 инструкции против 1 инструкции.
Для генерации ASM, как описано выше, вам нужно использовать инструмент под названием avr-objdump. Это включено в avr-gcc. Местоположение меняется в зависимости от ОС, поэтому его проще всего искать по имени.
avr-objdump может работать с файлами .hex, но в них отсутствуют первоначальный источник и комментарии. Если вы только что создали код, у вас будет файл .elf, который содержит эти данные. Опять же, расположение этих файлов зависит от ОС - самый простой способ найти их - включить подробную компиляцию в настройках и посмотреть, где хранятся выходные файлы.
Запустите команду следующим образом:
avr-objdump -S output.elf> asm.txt
И проверить вывод в текстовом редакторе.