Хотя я не использовал каждый существующий PIC-компилятор, существует два стиля. Стиль, который я использовал, статически распределяет все локальные переменные, анализируя граф вызовов программы. Если бы каждый возможный вызов был фактически выполнен, объем стековой памяти, потребляемой местными жителями, соответствовал бы тому, что потребовалось бы для статического выделения, с несколькими оговорками (описывающими поведение «стандартного» компилятора HiTech PICC-18 - другие могут отличаться )
- Функции Variadic обрабатываются путем определения хранилища локальных переменных в области действия caller и передачи двухбайтового указателя на это хранилище в вызываемую функцию.
- Для каждой другой сигнатуры косвенного указателя на функцию компилятор генерирует «псевдофункцию» в графе вызовов; все, что вызывает функцию этой сигнатуры, вызывает псевдофункцию, и эта псевдофункция вызывает каждую функцию с этой сигнатурой, для которой взят адрес.
В этом стиле компилятора последовательный доступ к локальным переменным будет таким же быстрым, как и последовательный доступ к глобальным переменным. Однако, кроме глобальных и статических переменных, явно объявленных как «ближние», которые должны составлять не более 64–128 байт (зависит от разных моделей PIC), глобальные и статические переменные для каждого модуля расположены отдельно от локальных переменных, и инструкции по смене банка необходимы для доступа к вещам в разных банках.
Некоторые компиляторы, которые я не использовал, используют опцию «расширенный набор команд». Эта опция поглощает 96 байтов «близкого» банка (или все это на PIC с менее чем 96 байтами) и использует его для доступа к 96 байтам относительно регистра FSR2. Это было бы замечательно, если бы в качестве фрейма стека использовались первые 16 или 32 байта. Использование 96 байтов означает отказ от всего «близкого» хранилища, что является довольно серьезным ограничением. Тем не менее, компиляторы, которые используют этот набор инструкций, могут обращаться к локальным переменным в стеке так же быстро, если не быстрее, чем глобальные переменные (не требуется переключение банков). Мне бы очень хотелось, чтобы у Microchip была возможность выделить только 16 байтов или около того для стекового фрейма, оставляя полезный объем оперативной памяти «общего банка», но, тем не менее, некоторым людям повезло с этим режимом.