Цитата(Xenia @ Aug 27 2011, 19:25)

Когда переменная объявлена с адресом памяти (например @14), то и компилятор использует ее, как память, даже тогда, когда адрес настолько мал, что налезает область на регистров.
Если хотите, чтобы переменная использовалась как регистр, то объявите ее дефайном, как синоним имени нужного вам регистра. Например так:
#define Old_PINB PORTE
#define New_PINB PORTF
Имена регистров ищите в хидере, соотвествующему вашему типу МК.
Вот здесь либо я Вас не понимаю, либо Вы меня. Поэтому постараюсь объяснить подробнее. В пункте Register Utilization я могу зарезервировать от одного (R15) до 12 (R4...R15) операционных регистров под глобальные переменные. Поскольку работать с переменными, расположенными в регистрах, можно быстрее, чем с переменными расположенными в ячейках ОЗУ, в критичных по времени функциях пытаюсь использовать такую возможность, что в моем случае вполне оправдано. Но компилятор генерирует не совсем оптимальный код, пример которого привел выше.
Объясните, пожалуйста, если я хочу старое и новое значения байтов, полученных из порта PINB, хранить именно в РОН и дальше в функции работать именно с данными в этих регистрах (естественно, учитывая ограничения для нижних 16 РОН у AVR), то чем Ваши вышеуказанные дефайны могут мне помочь? У меня Old_PINB и New_PINB являются однобайтовыми глобальными переменными, расположенными в регистрах R14 и R15 соответственно, а отнюдь не регистры портов PORTE и PORTF. Я ведь спрашивал, как, например, получить байт из порта B непосредственно в тот же регистр R15 (пересылка байта из порта в регистр возможна для всех 32 регистров, а не только верхней их половины), не привлекая сюда избыточно регистр R16.
Например, в подпрограмме обработки прерывания мне нужно получить новое значение, предварительно сохранив предыдущее, как старое. На ассемлере это "звучало" бы так:
CODE
...
MOV R14,R15
IN R15,PINB
RETI
А компилятор порождает код:
CODE
...
ST -Y, R16
MOV R14,R15
IN R16,PINB
MOV R15,R16
LD R16,Y+
RETI
А зачем мне эти лишние байты и лишние такты?