реклама на сайте
подробности

 
 
> IAR EWAVR - как избавиться от лишних команд?
kv_addr
сообщение Aug 27 2011, 14:37
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



В критичных по времени функциях использую зарезервированные РОН из нижней половины, в нижеуказанном примере r14 и r15:
CODE
...
volatile __regvar __no_init char Old_PINB @14;
volatile __regvar __no_init char New_PINB @15;
...
Old_PINB = New_PINB;
New_PINB = PINB;
...


Получаю в результате:
CODE
// 70 Old_PINB = New_PINB;
MOV R14, R15
// 71 New_PINB = PINB;
IN R16, 0x03
MOV R15, R16

В вышеуказанном примере последовательность команд IN R16,0x03 и MOV R15,R16 явно лишняя, достаточно было одной команды IN R15,0x03. Расходуется лишняя пара байтов и лишний такт. Казалось бы мелочь, но такого при работе с зарезервированными под переменные регистрами может набежать вполне прилично.

Да, конечно, можно написать критичные по времени модули на ассемблере, но все же, если бы можно было избежать подобных несуразностей при компиляции сишного кода, было бы всяко лучше.

Мог бы кто нибудь подсказать, как в EWAVR это можно побороть, или сия бага есть врожденная фича EWAVR?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Xenia
сообщение Aug 27 2011, 15:25
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Когда переменная объявлена с адресом памяти (например @14), то и компилятор использует ее, как память, даже тогда, когда адрес настолько мал, что налезает область на регистров.
Если хотите, чтобы переменная использовалась как регистр, то объявите ее дефайном, как синоним имени нужного вам регистра. Например так:
#define Old_PINB PORTE
#define New_PINB PORTF
Имена регистров ищите в хидере, соответствующему вашему типу МК.
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Aug 27 2011, 16:15
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Цитата(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

А зачем мне эти лишние байты и лишние такты?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- kv_addr   IAR EWAVR - как избавиться от лишних команд?   Aug 27 2011, 14:37
- - Xenia   Цитата(kv_addr @ Aug 27 2011, 20:15) В пу...   Aug 27 2011, 17:12
|- - Палыч   Цитата(Xenia @ Aug 27 2011, 21:12) от это...   Aug 27 2011, 18:33
|- - kv_addr   "Девушка, пожалуйста, не кричите очень громко...   Aug 27 2011, 18:56
|- - Xenia   Цитата(kv_addr @ Aug 27 2011, 22:56) Так ...   Aug 27 2011, 19:00
|- - kv_addr   Цитата(Xenia @ Aug 27 2011, 23:00) Постав...   Aug 27 2011, 19:15
|- - Палыч   Цитата(Xenia @ Aug 27 2011, 23:00) ... эф...   Aug 27 2011, 19:19
|- - kv_addr   Цитата(Палыч @ Aug 27 2011, 23:19) Нет, н...   Aug 27 2011, 19:31
|- - zhevak   Цитата(kv_addr @ Aug 28 2011, 01:31) Собс...   Aug 28 2011, 08:08
|- - kv_addr   Цитата(zhevak @ Aug 28 2011, 12:08) Ситуа...   Aug 28 2011, 13:05
- - Xenia   kv_addr, можно попросить вас выложить проектик для...   Aug 28 2011, 14:14
|- - kv_addr   Цитата(Xenia @ Aug 28 2011, 18:14) kv_add...   Aug 28 2011, 16:28
|- - Xenia   Цитата(kv_addr @ Aug 28 2011, 20:28) Нет ...   Aug 28 2011, 19:17
|- - kv_addr   Цитата(Xenia @ Aug 28 2011, 23:17) Мне на...   Aug 28 2011, 20:53
|- - Палыч   Цитата(Xenia @ Aug 28 2011, 23:17) с ваши...   Aug 31 2011, 05:37
|- - kv_addr   Цитата(Xenia @ Aug 28 2011, 23:17) Мне на...   Sep 2 2011, 13:41
|- - Xenia   Цитата(kv_addr @ Sep 2 2011, 17:41) И как...   Sep 2 2011, 15:04
|- - kv_addr   Цитата(Xenia @ Sep 2 2011, 19:04) Никак. ...   Sep 2 2011, 20:04
- - _Bill   Цитата(kv_addr @ Aug 27 2011, 18:37) В кр...   Aug 28 2011, 17:51
- - kv_addr   Цитата(_Bill @ Aug 28 2011, 21:51) Скорее...   Aug 28 2011, 18:34
- - _Bill   Цитата(kv_addr @ Aug 28 2011, 22:34) . Эт...   Aug 28 2011, 19:35


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 21:19
Рейтинг@Mail.ru


Страница сгенерированна за 0.01386 секунд с 7
ELECTRONIX ©2004-2016