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

 
 
> IAR AVR (Cи). вопрос о указателе на глобальную структуру, как заставить компилятор использовать рег. Z как постоянный указатель
ibiza11
сообщение Apr 1 2011, 12:12
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 13-01-09
Пользователь №: 43 304



Доброго времени суток уважаемые форумчане. На этом форуме давно, но отписываюсь не часто, практически по всем вопросам есть информация, за что всем посетителям и администрации поклон в ноги.
При написании кода всегда обращаю внимание на генерируемый ассемблерный листинг, при этом не заострял внимания на указатели.
Недавно обратил внимание на оч. интересный документ AVR035:Эффетивное программирование на Си для AVR (очень жалею, что давно его не прочел) sad.gif
В нем написан интересный способ уменьшения объема кода в случае использования множетсва глобальных переменных. Там предлагается объявить эти переменные как глобальную структуру и обращаться к каждой переменной
как к элементу структуры, при этом указатель на структуру всегда используется один и тот же, а переменные считываются командой LDD r16,Z+30 (соответственно командой STD записываются обратно). плюс
этой команды - использование считывания/записи со смещением, не изменяя при этом регистр Z.
я попробовал повторить пример из этой Application Note, все получилось как надо:
Цитата
typedef struct
{
int hour;
char min;
int sec;
}t;
t global;

__C_task void main1(void)
{
t *time=&global;
if(++time->sec==60)
{
time->sec=90;
time->min=70;
}
}

а это ассемблерный листинг, который генерируется в итоге:
Цитата
// 10 {
// 11 t *time=&global;

LDI R16, LOW(global)
LDI R17, (global) >> 8
MOVW R31:R30, R17:R16
// 12 if(++time->sec==60)
LDD R16, Z+2
INC R16
STD Z+2, R16
CPI R16, 60
BRNE ??main1_0
// 13 {
// 14 time->sec=90;

LDI R16, 90
STD Z+2, R16
// 15 time->min=70;
LDI R16, 70
STD Z+1, R16
// 16 }
// 17 }

Обратите внимание, что указатель инициализируется сразу в регистры r30,r31 (Z-регистр) и далее вообще не изменяется, а только используется с командами LDD, STD.
НО только я добавляю в цикл функцию delay, все кардинально меняется!!! blink.gif
Вот исходник
Цитата
typedef struct
{
int hour;
char min;
int sec;
}t;
t global;
extern void delay(unsigned int);

__C_task void main1(void)
{
delay(107);
t *time=&global;
if(++time->sec==60)
{
time->sec=90;
time->min=70;
}
}

А вот ассемблерный листинг
Цитата
// 12 delay(107);
FUNCALL main1, delay
LOCFRAME CSTACK, 0, STACK
LOCFRAME RSTACK, 2, STACK
ARGFRAME RSTACK, 0, STACK
LDI R16, 107
LDI R17, 0
RCALL delay
// 13 t *time=&global;
LDI R16, LOW(global)
LDI R17, (global) >> 8
MOVW R27:R26, R17:R16
// 14 if(++time->sec==60)
ADIW R27:R26, 2
LD R16, X

SBIW R27:R26, 2
INC R16
ADIW R27:R26, 2
ST X, R16
SBIW R27:R26, 2
CPI R16, 60
BRNE ??main1_0
// 15 {
// 16 time->sec=90;
LDI R16, 90
ADIW R27:R26, 2
ST X, R16

SBIW R27:R26, 2
// 17 time->min=70;
LDI R16, 70
ADIW R27:R26, 1
ST X, R16

SBIW R27:R26, 1
// 18 }
// 19 }
Обратите внимание, что теперь компилятору нафиг не сдался удобный регистр Z и команды LDD и STD вместе взятые. Вместо них он использует регистр X и каждый раз инкрементирует его на необходимый сдвиг, а считывает и записывает командами LD, ST, что естественно занимает больше времени чем команды LDD и STD. При оптимизации по скорости выполнения вообще заменяет указатель константой и обращается к каждому элементу структуры через команды STS LDS (занимающие в два раза больше программной памяти).
Вот код функции delay:
Цитата
void delay(volatile unsigned int ticks)
{
while(ticks)
ticks--;
}

volatile добавлен исключительно для того, чтобы компилятор не выбросил задержку из кода при оптимизации.
Теперь вопрос: Объясните почему так поступает компилятор с командами LDD и STD, и как ему указать что так делать не нужно?
Спасибо за внимание и понимание)

p.s. Если разместил тему не в том разделе, прошу модераторов перенести ее туда, где будет актуальнее.
уважаемые модераторы, изменил <codebox> на <quote> удобнее читать и есть возможность изменять цвет. в <code> нет возможности менять цвет текста.

Сообщение отредактировал ibiza11 - Apr 1 2011, 16:08
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ibiza11
сообщение Apr 4 2011, 16:04
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 54
Регистрация: 13-01-09
Пользователь №: 43 304



to =GM=, спасибо) blush.gif возможно, что я пробовал менять типы данных, чтобы посмотреть как ведет себя при этом IAR, при этом возможно, что я дизассемблер простого варианта скопипастил, а код уже нового варианта.
В вашем примере от WinAVR применена какая-нибудь оптимизация или это дебаг вариант? WinAVR также не использовал косвенную адресацию, а именно прямую (LDS/STS), как и IAR при оптимизации кода по скорости выполнения.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- ibiza11   IAR AVR (Cи). вопрос о указателе на глобальную структуру   Apr 1 2011, 12:12
- - pwl   Цитата(ibiza11 @ Apr 1 2011, 19:12) НО то...   Apr 1 2011, 17:07
- - ibiza11   Спасибо за ответ! единственный из всех, кто п...   Apr 1 2011, 20:04
|- - pwl   Цитата(ibiza11 @ Apr 2 2011, 03:04) Да и ...   Apr 2 2011, 00:19
- - ibiza11   Так ведь указатель инициализируется только после ф...   Apr 2 2011, 06:33
|- - pwl   Цитата(ibiza11 @ Apr 2 2011, 13:33) Так в...   Apr 2 2011, 17:49
- - ibiza11   не знаю как бороться с этим, придется пока смирить...   Apr 4 2011, 05:49
- - SasaVitebsk   Во-первых необязательно глобальные переменные объе...   Apr 4 2011, 09:10
- - ibiza11   Спасибо за ответ. Отвечать буду тоже по пунктам (е...   Apr 4 2011, 12:43
- - =GM=   2ibiza11 Как-то некрасиво себя IAR ведёт. В структ...   Apr 4 2011, 13:56
|- - =GM=   Ну так, приведите соответствующий код. Оптимизация...   Apr 4 2011, 22:19
- - ibiza11   Не понимаю, зачем Вам это, с таким упреком сказали...   Apr 5 2011, 06:56
|- - =GM=   Цитата(ibiza11 @ Apr 5 2011, 05:56) Не по...   Apr 5 2011, 11:36
- - ibiza11   Простите за недопонимание Не хотел обидеть Я тоже...   Apr 5 2011, 12:42
|- - =GM=   Цитата(ibiza11 @ Apr 5 2011, 11:42) ..пос...   Apr 5 2011, 13:45
|- - ibiza11   Цитата(=GM= @ Apr 5 2011, 17:45) Есть мод...   Apr 5 2011, 13:54
|- - =GM=   Документ doc0856i (тыц), с.96. Я не говорил, что и...   Apr 5 2011, 14:42
- - SasaVitebsk   Код 20 delay(107); \ 0000000...   Apr 5 2011, 13:20
- - ibiza11   SasaVitebsk, странно, у Вас компилятор не вызвал ф...   Apr 5 2011, 13:38
|- - SasaVitebsk   Цитата(ibiza11 @ Apr 5 2011, 17:38) SasaV...   Apr 6 2011, 05:46
- - ibiza11   Спасибо всегда думал, что я знаю этот документ)))...   Apr 5 2011, 21:07
- - =GM=   Если в памяти, то от 0х60   Apr 5 2011, 21:25


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

 


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


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