Цитата(Old1 @ Mar 17 2006, 20:53)

Компилятор глобальные переменные по умолчанию помещает в SRAM, поэтому и обращается к ним через указатель, времени это занимает больше, если сравнивать с обращениями к регистровому файлу или к io-регистрам (поэтому обычно рекомендуют стараться меньше использовать глобальные переменные). Для того чтобы уменьшить время выполнения обработчика прерывания можно посоветовать объявить глобальную переменную как регистровую или разместить ее в неиспользуемых io-регистрах.
Ответ большей частью верный, но непонятный для начинающих. Попробую пояснить.
Имеем три вида переменных в языке C:
1) Глобальные, объявленные на внешнем уровне.
2) Локальные статические, объявленные внутри функции и сохраняющие свои значения между вызовами.
3) Локальные автоматические, объявленные внутри функции и не сохраняющие своих значений.
Переменные (1) компилятор размещает в SRAM. Слово register конкретным компилятором для глобальных переменных не будет удовлетворено, так как неизвестно, что с этими регистрами сделают другие функции. Для размещения глобальной переменной в регистре есть опция конкретного компилятора lock registers и ключевое слово __regvar (см. документацию). Залочив несколько регистров (то есть, зарезервировав их под статические переменные), вся программа и используемые библиотеки должна быть откомпилирована с такой же опцией, иначе на стадии линковки будет ошибка. Есть еще вариант размещения констант в памяти программ - const __flash, но это не относится к изменяемым переменным.
Кстати, зарезервировать регистры под переменные мало: надо еще и явно разместить их там (см. документацию). Иначе будет только хуже или, как минимум, не лучше. А хуже потому, что компилятор ограничен в использовании всех свободных регистров, а если там ничего не разместили, то выигрыша не будет. Не все переменные следует делать регистровыми - это зависит от их использования, надо пробовать. Иногда на одной переменной выигрыш десятки байтов, на другой - почти ничего, а на третьей получаем даже проигрыш.
Локальные статические переменные (2) компилятор также размещает в SRAM (из ответа можно понять, что нет). Отличие от (1) - только в области видимости (конкретная функция). Все справедливо и в отношении игнорирования слова register. __regvar использовать, скорее всего, тоже не удастся: насколько помню, компилятор допускает его применение только для глобальных переменных. Почему обращение к локальным static менее эффективно, чем к глобальным - не скажу, не видя фрагмента кода.
Локальные автоматические переменные (3) - вот тут возможны варианты. Классически эти переменные размещаются в стеке, расположенном тоже в SRAM. Однако в данном случае компилятор и без всяких слов register будет пытаться разместить максимум автоматических переменных в регистрах. Сохранять их между вызовами не нужно, а есть достаточное количество регистров, которые функция может использовать и не обязана сохранять (см. документацию). Работа с регистрами обычно эффективнее, это верно. Но использовать минимум глобальных переменных рекомендуют вовсе не по этой причине, а из соображений стиля программирования и читабельности программ. Остальное более-менее вторично и зависит от конкретных особенностей компилятора.
Тут есть много нюансов. Например, единственный вызов функции без параметров, занимающий слово (2 байта) может очень неслабо увеличить размер некоей функции. Почему? А потому что вызванная функция может использовать половину регистров, и весь выигрыш от размещения локальных auto переменных в регистрах будет съеден необходимостью их сохранить перед этим вызовом, а потом восстановить.
Почему компилятор использует обращение через "указатель"? Ряд команд специально сделан для работы с индексированными данными. Например, в регистровую пару Z может быть загружен начальный адрес структуры, а потом к ее членам можно обращаться одной командой через Z+смещение. Компактно и удобно. Этот прием компилятор может использовать и для доступа к локальным переменным, и для глобальных с целью экономии кода.
Насчет сложного кода в выражениях: заочно ответить нельзя. В таких случаях надо писать иначе: вот фрагмент 1 (кусок кода), вот фрагмент 2 (кусок кода). Первый занимает на 20 байтов больше. В чем причина? Иногда ответить на этот вопрос вообще нельзя, не видя описания переменных и т.п. Часто просто удобнее писать по частям, заводя по ходу дела промежуточные переменные. Не следует беспокоиться: при высоких уровнях оптимизации компилятор так или иначе не будет хранить то, что дальше по тексту не требуется. А читабельность это может поднять.
Про массивы в прерывании. То же самое. Не видя кода, нельзя сказать, почему компилятор "ругается". Как минимум, следует указывать сообщение об ошибке. А сэкономить можно много как. Например, объявить таблицу как const __flash, разместив ее тем самым не в SRAM (которое заполняется кодом инициализации из того же flash при запуске программы), а непосредственно во flash. Правда, доступ будет чуть сложнее, но зато таблица не займет оперативной памяти, что иногда важнее. А, кстати, а как на самом деле объявлялась таблица внутри? Надеюсь, что static? Иначе бедному компилятору пришлось бы ее инициализировать при каждом входе в функцию... Может, это и не понравилось? В общем, код в студию.
11 байт: то же самое. Бесцельно компилятор не выделяет лишние байты в конце. Причина обычно всегда есть. Но без фрагмента текста понять ее сложно. Мало кто на этом форуме умеет гадать на кофейной гуще
Цитата(SasaVitebsk @ Mar 17 2006, 21:38)

Цитата(Old1 @ Mar 17 2006, 22:53)

Компилятор глобальные переменные по умолчанию помещает в SRAM
Компилятор
в любом случае помещает эти переменные в SRAM. Но в первом описанном случае помещает ещё и указатели на эти переменные. Ну и обращается к ним ... соответственно.
Компилятор не помещает их в SRAM, если явно указано, например,
char __regvar __noinit c @ 15;
При этом глобальная переменная c будет размещена не в SRAM, а в регистре, который мы обязаны залочить на уровне всего проекта опцией компилятора или IDE. Тут ответ был совершенно правильный.
А размещать для статических переменных еще и указатели на них, помимо самих переменных... помилуйте, ради чего? Повторю, что не видя конкретного кода в конкретном контексте, сказать на 100% просто невозможно, можно лишь гадать.