ЧТО ЭТО
Как и Хавьер Сильва Ортиз , упомянутый в комментарии, это таблица прерываний, расположенная в самом начале памяти программы.
Первая инструкция - это вектор RESET, и мы можем видеть адрес, на который она указывает. Другими словами, сразу после сброса MCU выполняет первую инструкцию JMP 0x00003834
и перемещается точно в начало программы.
Кстати, взгляните на другие инструкции JMP
: все ониуказывая на тот же адрес, так называемый __bad_interrupt()
, где находится единственная инструкция RETI
. Если одно из этих прерываний случайно срабатывает (и ваша программа не знает, что делать с этим прерыванием), то одиночная инструкция RETI
мгновенно завершает это прерывание, и программа возвращается к нормальному выполнению.
ИЗБЕГАЯ ЭТОГО
Если вы абсолютно уверены, что в вашем загрузчике нет возможных прерываний, вы можете избежать таблицы прерываний, передавая флаг CFLAGS = -nostartfiles
компилятору.
БУДЬТЕ ОСТОРОЖНЫ!
Некоторые другие вещи будут нарушены флагом -nostartfiles
!
Проблема в том, что avr-gcc в начале создает магиюскомпилированной программы. Есть некоторые общие операции, которые компилятор размещает сразу после таблицы прерываний. Эти операции делятся на разделы, такие как __ctors_end
, __do_copy_data
, __do_clear_bss
и так далее. Для чего они нужны?
Прежде всего, регистр r1
обнуляется в секции __ctors_end
. Почему это так важно? r1
используется по умолчанию каждый раз, когда компилятор сравнивает другие регистры с нулем. Да, avr-gcc знает об этом «магическом» r1
и не записывает в него, но есть некоторые случаи, когда он изменяется (например, результат умножения помещается в пару регистров r0: r1), икаждый раз, когда это изменяется, avr-gcc обнуляет это. Все может пойти не так, если r1
не установлен на ноль во время запуска ...
Другая вещь, которая делается в начале программы, - это установка на ноль переменных, которые должны быть равны нулю. Это делается в разделе __do_clear_bss
. Просто представьте, что вы ожидаете, что что-то будет равно нулю, и это не так. Каковы последствия?
Другая важная операция - копирование данных из памяти программы в SRAM. Это делается в разделе __do_copy_data
. Отключение __do_copy_data
приводит к поломке всех статических массивов.
AND? ..
Вы должны быть очень осторожны, пытаясь оптимизировать таблицу прерываний с помощью -nostartfiles
. Делайте это, только если вы на 200% уверены, что происходит.