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

 
 
> 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, 17:12
Сообщение #2


Гуру
******

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



Цитата(kv_addr @ Aug 27 2011, 20:15) *
В пункте Register Utilization я могу зарезервировать от одного (R15) до 12 (R4...R15) операционных регистров под глобальные переменные. Поскольку работать с переменными, расположенными в регистрах, можно быстрее, чем с переменными расположенными в ячейках ОЗУ, в критичных по времени функциях пытаюсь использовать такую возможность, что в моем случае вполне оправдано. Но компилятор генерирует не совсем оптимальный код, пример которого привел выше.

Резервирование это одно, а компиляция через инструкцию IN - другое. Резервирование означает только то, что компилятору запрещается использовать эти регистры при генерации C-кода (причем за библиотеки компилятор отвественности не несет, т.к. получает их уже скомпилированными). Нечего кроме этого операция резервирование не означает. Т.е. только от этого память не станет регистром, а регистр не станет памятью.

С точки зрения компилятора регистр отличается от памяти способом адресации. Хотя с точки зрения электронщика это может быть одно и тоже sm.gif. В отношении регистра компилятор использует команды IN и OUT, тогда как к памяти обращается по ее адресу. В этом и состоит это отличие.

Регистры объявлены в хидере с помощью определения SFR_B или ему подобных, описанных в iomacro.h. Эти определения сильно компиляторозависимые, а потому не стоит повторять те приемы, которыми они там определятся как регистры, хотя самим SFR_B пользоваться вполне можно. Например так:
SFR_B(Old_PINB, 14)
SFR_B(New_PINB, 15)
Но лучше, все-таки так не делать, а найти в хидере уже определенные имена регистров из области 14-го и 15-го байта. Там должно быть что-то вроде этого:
SFR_B(?????, 0xE)
SFR_B(?????, 0xF)
Вот с этими именами, которые у меня записаны, как "?????", и нужно определить тождество через #define и тогда такие клоны тоже будут использоваться компилятором, как регистры.

Попытки же использовать зарезервированное среди регистров место по адресу (@14 или @15) приводит лишь к тому, что это место используется, как память. Т.е. обращение к нему будет происходить по адресам 14 или 15, а не регистровыми опрациями IN/OUT.

Цитата(kv_addr @ Aug 27 2011, 20:15) *
Объясните, пожалуйста, если я хочу старое и новое значения байтов, полученных из порта PINB, хранить именно в РОН и дальше в функции работать именно с данными в этих регистрах (естественно, учитывая ограничения для нижних 16 РОН у AVR), то чем Ваши вышеуказанные дефайны могут мне помочь?

Дефайны помогают тем, что отожествляют ваши имена Old_PINB и New_PINB с именами регистров, а не с памятью. А это позволяет обращаться к ним, как к регистрам, используя команды IN/OUT. А ваше определение этих имен, как переменных, с указанными для них адресами (@14 или @15), является определением для ячеек памяти. По этой причине компилятор в их отношении команды IN/OUT не использует.

Я понимаю, что вы хотели бы, чтобы компилятор сам догадался, что по адресам 14 и 15 находятся регистры. Однако догадаться об этом он не может. Причина в том, что эти адреса считаются от начала сегмента кода! А где начинается сегмент кода знает только линкер, а компилятор этого не знает и знать не должен. Поэтому в данном случае вина лежит целиком на вашем корявом программировании, а не на компиляторе замечательной фирмы IAR. sm.gif

Цитата(kv_addr @ Aug 27 2011, 20:15) *
У меня Old_PINB и New_PINB являются однобайтовыми глобальными переменными, расположенными в регистрах R14 и R15 соответственно, а отнюдь не регистры портов PORTE и PORTF.

А в моем AT90USB647 по адресам 14 и 15 находятся именно регистры PORTE и PORTF! Вы ведь поленились назвать тип вашего МК? А раз так, то не имеете права выставлять мне претензий за то, что я ваши 14-ю и 15-ю ячейки неправильно отнесла. Телепатическими способностями в отношении вас я не обладаю, поэтому в своем прошлом ответе ограничилась вежливой формулировкой "имена регистров ищите в хидере, соответствующему вашему типу МК". Почему бы вам и в самом деле не посмотреть, как называются у вашего МК регистры, находящиеся в 14-ом и 15-ом байтах?
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- kv_addr   IAR EWAVR - как избавиться от лишних команд?   Aug 27 2011, 14:37
- - Xenia   Когда переменная объявлена с адресом памяти (напри...   Aug 27 2011, 15:25
|- - kv_addr   Цитата(Xenia @ Aug 27 2011, 19:25) Когда ...   Aug 27 2011, 16:15
|- - Палыч   Цитата(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 - 19:33
Рейтинг@Mail.ru


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