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

 
 
> Winavr сокращает функцию, если переменные размещены в регистрах
A.l.e.x.
сообщение Jun 10 2008, 11:54
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Помогите разобраться с WINAVR. При размещении переменных в регистрах компилятор ведёт себя подозрительно: сокращает функции, в которых они используются. 07.gif Но при обычном объявлении всё работает. Подскажите, где может быть ошибка?

Код
#include <avr/io.h>
#include <avr/interrupt.h>
volatile register unsigned long count_ms asm("r4");
volatile register unsigned char flag_ms asm("r8");
/////////////////////////////////////////////////////////////////////////////////////////////////
void timer_ms(unsigned long value)
{
    count_ms = value;
    flag_ms = 0;
    while(flag_ms == 0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIM0_COMPA_vect)
{
    if(count_ms){--count_ms;}
    else{flag_ms = 1;}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
    TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(0<<WGM00);    //CTC
    TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00);        // FCPU/8
    OCR0A = 149;
    TIMSK0 = (0<<OCIE0B)|(1<<OCIE0A)|(0<<TOIE0);
    sei();
    
    
    while(1){
        timer_ms(100);
        PORTB ^= 0x01;
    }
}

Прикрепленные файлы
Прикрепленный файл  timer_ms.rar ( 7.91 килобайт ) Кол-во скачиваний: 41
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aesok
сообщение Jun 10 2008, 12:15
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Регистровые volatile переменные в GCC не работают.

Анатолий

AVRGCC ignores "volatile" keyword for "register" variables
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17336

Сообщение отредактировал aesok - Jun 10 2008, 12:28
Go to the top of the page
 
+Quote Post
A.l.e.x.
сообщение Jun 10 2008, 12:36
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Цитата(aesok @ Jun 10 2008, 15:15) *
Регистровые volatile переменные в GCC не работают.

Анатолий

AVRGCC ignores "volatile" keyword for "register" variables
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17336


И каков же выход? Использовать IAR?
Go to the top of the page
 
+Quote Post
dimka76
сообщение Jun 10 2008, 12:55
Сообщение #4


developer
****

Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032



Цитата(A.l.e.x. @ Jun 10 2008, 15:36) *
И каков же выход? Использовать IAR?


Используйте GPIO0, GPIO1, GPIO2. В принципе можно даже использовать любые незадействованные SFR с адресом 0х00 - 0х1F


--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
Go to the top of the page
 
+Quote Post
A.l.e.x.
сообщение Jun 10 2008, 14:02
Сообщение #5


Участник
*

Группа: Свой
Сообщений: 69
Регистрация: 4-02-08
Из: Винница
Пользователь №: 34 732



Цитата(dimka76 @ Jun 10 2008, 15:55) *
Используйте GPIO0, GPIO1, GPIO2. В принципе можно даже использовать любые незадействованные SFR с адресом 0х00 - 0х1F

Если не трудно, подскажите как использовать SFR в дипазоне 0x09...0x13 (записать/прочитать данные 2-х или 4-х байтные)?


Цитата(singlskv @ Jun 10 2008, 16:59) *
Просто уберите volatile при объявлении регистровой переменной,
все должно скомпилится правильно.

Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 10 2008, 14:06
Сообщение #6


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(A.l.e.x. @ Jun 10 2008, 18:02) *
Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект...
А какая версия WinAVR ?
Скомпилируйте с листингом и покажите его.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 10 2008, 16:28
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(singlskv @ Jun 10 2008, 18:06) *
А какая версия WinAVR ?


Все версии avr-gcc так работают.

Анатолий.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 10 2008, 17:44
Сообщение #8


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Jun 10 2008, 20:28) *
Все версии avr-gcc так работают.
Ну это как минимум не так smile.gif

WinAVR20060421(Gcc 3.4.6):
CODE

00000048 <timer_ms>:
register unsigned long count_ms asm("r4");
register unsigned char flag_ms asm("r8");
/////////////////////////////////////////////////////////////////////////////////////////////////
void timer_ms(unsigned long value)
{
48: b9 2f mov r27, r25
4a: a8 2f mov r26, r24
4c: 97 2f mov r25, r23
4e: 86 2f mov r24, r22
count_ms = value;
50: 48 2e mov r4, r24
52: 59 2e mov r5, r25
54: 6a 2e mov r6, r26
56: 7b 2e mov r7, r27
flag_ms = 0;
58: 88 24 eor r8, r8
while(flag_ms == 0);
5a: 88 20 and r8, r8
5c: f1 f3 breq .-4 ; 0x5a <timer_ms+0x12>
5e: 08 95 ret

00000060 <__vector_6>:
}
/////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIM0_COMPA_vect)
{
60: 1f 92 push r1
62: 0f 92 push r0
64: 0f b6 in r0, 0x3f ; 63
66: 0f 92 push r0
68: 11 24 eor r1, r1
if(count_ms){--count_ms;}
6a: 41 14 cp r4, r1
6c: 51 04 cpc r5, r1
6e: 61 04 cpc r6, r1
70: 71 04 cpc r7, r1
72: 31 f0 breq .+12 ; 0x80 <__vector_6+0x20>
74: 08 94 sec
76: 41 08 sbc r4, r1
78: 51 08 sbc r5, r1
7a: 61 08 sbc r6, r1
7c: 71 08 sbc r7, r1
7e: 02 c0 rjmp .+4 ; 0x84 <__vector_6+0x24>
else{flag_ms = 1;}
80: 88 24 eor r8, r8
82: 83 94 inc r8
84: 0f 90 pop r0
86: 0f be out 0x3f, r0 ; 63
88: 0f 90 pop r0
8a: 1f 90 pop r1
8c: 18 95 reti

0000008e <main>:
}
/////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
8e: cf e9 ldi r28, 0x9F ; 159
90: d0 e0 ldi r29, 0x00 ; 0
92: de bf out 0x3e, r29 ; 62
94: cd bf out 0x3d, r28 ; 61
TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(0<<WGM00); //CTC
96: 82 e0 ldi r24, 0x02 ; 2
98: 8f bd out 0x2f, r24 ; 47
TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00); // FCPU/8
9a: 83 bf out 0x33, r24 ; 51
OCR0A = 149;
9c: 85 e9 ldi r24, 0x95 ; 149
9e: 86 bf out 0x36, r24 ; 54
TIMSK0 = (0<<OCIE0B)|(1<<OCIE0A)|(0<<TOIE0);
a0: 84 e0 ldi r24, 0x04 ; 4
a2: 89 bf out 0x39, r24 ; 57
sei();
a4: 78 94 sei

while(1){
timer_ms(100);
a6: 64 e6 ldi r22, 0x64 ; 100
a8: 70 e0 ldi r23, 0x00 ; 0
aa: 80 e0 ldi r24, 0x00 ; 0
ac: 90 e0 ldi r25, 0x00 ; 0
ae: cc df rcall .-104 ; 0x48 <timer_ms>
PORTB ^= 0x01;
b0: 88 b3 in r24, 0x18 ; 24
b2: 91 e0 ldi r25, 0x01 ; 1
b4: 89 27 eor r24, r25
b6: 88 bb out 0x18, r24 ; 24
b8: f6 cf rjmp .-20 ; 0xa6 <__stack+0x7>


как видно, оверхед только здесь:
Код
  48:    b9 2f           mov    r27, r25
  4a:    a8 2f           mov    r26, r24
  4c:    97 2f           mov    r25, r23
  4e:    86 2f           mov    r24, r22
и здесь:
Код
  b2:    91 e0           ldi    r25, 0x01; 1

Но при этом код абсолютно корректный !

Можно ли получить такой же компактный/быстрый код на Gcc 4.x.x ???
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 10 2008, 18:12
Сообщение #9


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(singlskv @ Jun 10 2008, 23:44) *
Можно ли получить такой же компактный/быстрый код на Gcc 4.x.x ???


Увы sad.gif

Без оптимизации выходит:
Код
void timer_ms(unsigned long value)
{
  48:    df 93           push    r29
  4a:    cf 93           push    r28
  4c:    00 d0           rcall    .+0      ; 0x4e <timer_ms+0x6>
  4e:    00 d0           rcall    .+0      ; 0x50 <timer_ms+0x8>
  50:    cd b7           in    r28, 0x3d; 61
  52:    de b7           in    r29, 0x3e; 62
  54:    69 83           std    Y+1, r22; 0x01
  56:    7a 83           std    Y+2, r23; 0x02
  58:    8b 83           std    Y+3, r24; 0x03
  5a:    9c 83           std    Y+4, r25; 0x04
    count_ms = value;
  5c:    49 80           ldd    r4, Y+1; 0x01
  5e:    5a 80           ldd    r5, Y+2; 0x02
  60:    6b 80           ldd    r6, Y+3; 0x03
  62:    7c 80           ldd    r7, Y+4; 0x04
    flag_ms = 0;
  64:    88 24           eor    r8, r8
    while(flag_ms == 0);
  66:    88 2d           mov    r24, r8
  68:    88 23           and    r24, r24
  6a:    e9 f3           breq    .-6      ; 0x66 <timer_ms+0x1e>
}
  6c:    0f 90           pop    r0
  6e:    0f 90           pop    r0
  70:    0f 90           pop    r0
  72:    0f 90           pop    r0
  74:    cf 91           pop    r28
  76:    df 91           pop    r29
  78:    08 95           ret


и так далее, а начиная с -O1:
Код
void timer_ms(unsigned long value)
{
  48:    ff cf           rjmp    .-2      ; 0x48 <timer_ms>


Это avr-gcc (GCC) 4.4.0 20080530 (experimental).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 10 2008, 19:32
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(AHTOXA @ Jun 10 2008, 23:12) *
и так далее, а начиная с -O1:
Код
void timer_ms(unsigned long value)
{
  48:    ff cf           rjmp    .-2     ; 0x48 <timer_ms>


Это avr-gcc (GCC) 4.4.0 20080530 (experimental).

gcc-4.2.2 начиная c -O1:
Код
   7:test.c        **** void timer_ms(unsigned long value)
   8:test.c        **** {
  79                    /* prologue: frame size=0 */
  80                    /* prologue end (size=0) */
   9:test.c        ****    count_ms = value;
  83 0000 2B01                  movw r4,r22
  84 0002 3C01                  movw r6,r24
  10:test.c        ****    flag_ms = 0;
  87 0004 8824                  clr r8
  88                    .L2:
  11:test.c        ****    while(flag_ms == 0);
  91 0006 8820                  tst r8
  92 0008 01F0                  breq .L2
  93                    /* epilogue: frame size=0 */
  94 000a 0895                  ret
  95                    /* epilogue end (size=1) */
  96                    /* function timer_ms size 6 (5) */
  12:test.c        **** }


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 11 2008, 12:33
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(alx2 @ Jun 11 2008, 01:32) *
gcc-4.2.2 начиная c -O1:


Странно...
avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221):
Код
00000048 <timer_ms>:
  48:    2b 01           movw    r4, r22
  4a:    3c 01           movw    r6, r24
  4c:    88 24           eor    r8, r8
  4e:    ff cf           rjmp    .-2      ; 0x4e <timer_ms+0x6>


avr-gcc.exe (GCC) 4.1.2 (WinAVR 20070525):
Код
void timer_ms(unsigned long value)
{
  4a:    46 2e           mov    r4, r22
  4c:    57 2e           mov    r5, r23
  4e:    68 2e           mov    r6, r24
  50:    79 2e           mov    r7, r25
    count_ms = value;
    flag_ms = 0;
  52:    88 24           eor    r8, r8
  54:    ff cf           rjmp    .-2      ; 0x54 <timer_ms+0xa>


А у Вас какой GCC 4.2.2? Хочу такой жеsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 11 2008, 13:54
Сообщение #12


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(AHTOXA @ Jun 11 2008, 16:33) *
Странно...
avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221):
.....................
avr-gcc.exe (GCC) 4.1.2 (WinAVR 20070525):
.....................
Это с volatile или без перед register ?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 11 2008, 17:44
Сообщение #13


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(singlskv @ Jun 11 2008, 19:54) *
Это с volatile или без перед register ?


Это без volatile.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 11 2008, 18:48
Сообщение #14


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(AHTOXA @ Jun 11 2008, 21:44) *
Это без volatile.
Да, похоже единственный правильный вариант для gcc 4.x.x без раздувания
кода и данных это с асм вставкой:
Код
#include <avr/io.h>
#include <avr/interrupt.h>

/////////////////////////////////////////////////////////////////////////////////////////////////
volatile register unsigned long count_ms asm("r4");
register unsigned char flag_ms asm("r8");

static void timer_ms(unsigned long value)
{
    count_ms = value;
    flag_ms = 0;
    __asm__ __volatile__("and   r8,r8\n\t"\
                         "breq  .-4");
}
/////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIM0_COMPA_vect)
{
    if(count_ms){--count_ms;}
    else{flag_ms = 1;}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
    TCCR0A = (0<<COM0A1)|(0<<COM0A0)|(0<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(0<<WGM00);    //CTC
    TCCR0B = (0<<FOC0A)|(0<<FOC0B)|(0<<WGM02)|(0<<CS02)|(1<<CS01)|(0<<CS00);        // FCPU/8
    OCR0A = 149;
    TIMSK0 = (0<<OCIE0B)|(1<<OCIE0A)|(0<<TOIE0);
    sei();
    
    
    while(1){
        timer_ms(100);
        PORTB ^= 0x01;
    }
}

При этом код правильный и компактный WinAVR20070525:
Код
  88:    94 e6           ldi    r25, 0x64; 100
  8a:    49 2e           mov    r4, r25
  8c:    51 2c           mov    r5, r1
  8e:    61 2c           mov    r6, r1
  90:    71 2c           mov    r7, r1
  92:    88 20           and    r8, r8
  94:    f1 f3           breq    .-4     ; 0x92 <main+0x1a>
    while(1){
        timer_ms(100);
        PORTB ^= 0x01;
  96:    88 b3           in    r24, 0x18; 24
  98:    91 e0           ldi    r25, 0x01; 1
  9a:    89 27           eor    r24, r25
  9c:    88 bb           out    0x18, r24; 24
  9e:    f4 cf           rjmp    .-24    ; 0x88 <main+0x10>


Цитата(aesok @ Jun 10 2008, 16:15) *
AVRGCC ignores "volatile" keyword for "register" variables
А вот это не совсем так, оно не игнорируется целиком, но логика работы при этом
мягко говоря странная... sad.gif
результат при компиляции прерывания:
volatile register unsigned long count_ms asm("r4");
Код
ISR(TIM0_COMPA_vect)
{
  4a:    1f 92           push    r1
  4c:    0f 92           push    r0
  4e:    0f b6           in    r0, 0x3f; 63
  50:    0f 92           push    r0
  52:    11 24           eor    r1, r1
    if(count_ms){--count_ms;}
  54:    41 14           cp    r4, r1
  56:    51 04           cpc    r5, r1
  58:    61 04           cpc    r6, r1
  5a:    71 04           cpc    r7, r1
  5c:    31 f0           breq    .+12    ; 0x6a <__vector_6+0x20>
  5e:    08 94           sec
  60:    41 08           sbc    r4, r1
  62:    51 08           sbc    r5, r1
  64:    61 08           sbc    r6, r1
  66:    71 08           sbc    r7, r1
  68:    02 c0           rjmp    .+4     ; 0x6e <__vector_6+0x24>
    else{flag_ms = 1;}
  6a:    88 24           eor    r8, r8
  6c:    83 94           inc    r8
  6e:    0f 90           pop    r0
  70:    0f be           out    0x3f, r0; 63
  72:    0f 90           pop    r0
  74:    1f 90           pop    r1
  76:    18 95           reti
Здесь все ок.

без volatile,
register unsigned long count_ms asm("r4");
Код
ISR(TIM0_COMPA_vect)
{
  4a:    1f 92           push    r1
  4c:    0f 92           push    r0
  4e:    0f b6           in    r0, 0x3f; 63
  50:    0f 92           push    r0
  52:    11 24           eor    r1, r1
  54:    8f 93           push    r24
  56:    9f 93           push    r25
  58:    af 93           push    r26
  5a:    bf 93           push    r27
    if(count_ms){--count_ms;}
  5c:    41 14           cp    r4, r1
  5e:    51 04           cpc    r5, r1
  60:    61 04           cpc    r6, r1
  62:    71 04           cpc    r7, r1
  64:    31 f0           breq    .+12    ; 0x72 <__vector_6+0x28>
  66:    08 94           sec
  68:    41 08           sbc    r4, r1
  6a:    51 08           sbc    r5, r1
  6c:    61 08           sbc    r6, r1
  6e:    71 08           sbc    r7, r1
  70:    02 c0           rjmp    .+4     ; 0x76 <__vector_6+0x2c>
    else{flag_ms = 1;}
  72:    81 e0           ldi    r24, 0x01; 1
  74:    88 2e           mov    r8, r24
  76:    bf 91           pop    r27
  78:    af 91           pop    r26
  7a:    9f 91           pop    r25
  7c:    8f 91           pop    r24
  7e:    0f 90           pop    r0
  80:    0f be           out    0x3f, r0; 63
  82:    0f 90           pop    r0
  84:    1f 90           pop    r1
  86:    18 95           reti
Ну и зачем здесь сохраняются r24-r27 ?
и почему нельзя было обойтись
eor r8,r8
inc r8
как в предыдущем коде ?
замечу при этом что добавляли/убирали volatile ВООБЩЕ У ДРУГОЙ ПЕРЕМЕННОЙ !
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 11 2008, 19:04
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Второй раз повторяю, GCC не поддерживает volatile register переменные. Не
поддерживает - это значит что нет гарантии что любой код использующий
volatile register переменные будет работать при любом уровне оптимизации. К
сожалению варинг сообщающий об этом пропал где-то в 2005 году и если я
правильно понял его вернули в феврале 2008. Попробуйте откомпилировать
тестовый пример с "volatile register" GCC 4.4 с клюем -Wall. Или с ключом
-Wvolatile-register-var на 4.3.

Анатолий.

Сообщение отредактировал aesok - Jun 11 2008, 19:10
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 11 2008, 19:33
Сообщение #16


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Jun 11 2008, 23:04) *
Второй раз повторяю, GCC не поддеживае volatile register переменные. Не подерживает - это значит что нет гарантии что любой код использующий volatile register переменные будет работать при любом уровне оптимизации.
Но в Gcc 3.4.6 без volatile это ведь работало правильно при любом коде!
Цитата
К сожалению варинг сообщающий об этом пропал гте-то в 2005 году и если я правильно панял его вернули в феврале 2008.
Да, его вернули http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34351
Вопрос в том правильно ли было выключать/включать варнинги вместо того чтобы обращение
к регистровым переменным пометить как неоптимизируемые(собственно как это и происходит при
асм вставке) ?


Ну и еще один вопрос,
по Вашему мнению можно вообще пользоваться регистровыми переменными(без volatile) в GCC ?
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 11 2008, 20:57
Сообщение #17


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(singlskv @ Jun 11 2008, 23:33) *
Ну и еще один вопрос,
по Вашему мнению можно вообще пользоваться регистровыми переменными(без volatile) в GCC ?


Только если они не используются в прерываниях.

Во первых безопасно можно использовать только регистры r2-r7, остальные могут
использоваться компилятором.

Во вторых почему нельзя использовать глобальные регистровые переменные в
обработчиках прерываний. r2-r7 - это call-saved регистры, то-есть если есть
большая функция для которой генерируется код использующий эти регистры то при
в входе в функцию r2-r7 сохраняться в стеке при выходе из нее восстановятся.
Допустим такая функция бала вызвана из main, при этом содержимое регистровой
переменой временно сохранилось в стеке. В этот момент происходит прерывание и
обработчик прерывания работая с регистровой перемеренной (r2-r7) работает не со
своими данными а с данными функции которую он прервал. После завершения
обработчика прерывания локальные значения r2-r7 в функции будут искажены, а
после возврата из этой функции r2-r7 (глобальная переменная) будут
восстановлены из стека, и если обработчик прерывания сохранял значения в
регистровой переменной то оно будет заменено на предыдущее.


Анатолий.

Цитата(singlskv @ Jun 12 2008, 00:13) *
register uint8_t flags asm("r16");

Чюш!!!! r16 используется для передачи аргументов функции. Это будет работать до тех пор пока в программе не появится функция у которой общий размер аргументов будет превышать 8 байт.

Анатолий.



Цитата(singlskv @ Jun 12 2008, 00:13) *
В посте №22 я уже показывал что еще как помечает, только делает он это
как-то ммм... странновато...


Если чтото работает странно - это называеться не работает.

Анатолий.

Цитата(singlskv @ Jun 12 2008, 00:13) *
В посте №22 я уже показывал что еще как помечает, только делает он это
как-то ммм... странновато...


Цитата
Re: [PATCH] volatile global register variable
From: Ian Lance Taylor <ian at airs dot com>
To: "Joseph S. Myers" <joseph at codesourcery dot com>
Cc: David Edelsohn <dje at watson dot ibm dot com>, gcc-patches at gcc dot gnu dot org, Mark Mitchell <mark at codesourcery dot com>, bergner at vnet dot ibm dot com
Date: 09 Nov 2005 11:33:17 -0800
Subject: Re: [PATCH] volatile global register variable
References: <200511091628.jA9GSTq17300@makai.watson.ibm.com><Pine.LNX.4.64.0511091812330.10480@digraph.polyomino.org.uk>


They "don't work as you might wish" because at the RTL level a global
register variable is stored as a REG, and there is no way to mark a
REG as volatile.


Сообщение отредактировал aesok - Jun 11 2008, 20:56
Go to the top of the page
 
+Quote Post
singlskv
сообщение Jun 11 2008, 21:15
Сообщение #18


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(aesok @ Jun 12 2008, 00:39) *
Только если они не используются в прерываниях.
а нафига они тогда вобще нужны smile.gif
Цитата
Во первых безопасно можно использовать только регистры r2-r7, остальные могут
использоваться компилятором.
Да именно так и написанно в доке, но для обсуждаймого примера это не существенно.
Цитата
Во вторых почему нельзя использовать глобальные регистровые переменные в
обработчиках прерываний.
...............................................
Это все понятно, действительно для long long, float и др библиотек можно нарваться,
Ну а если все это не используется ?

Цитата(aesok @ Jun 12 2008, 00:57) *
Чюш!!!! r16 используется для передачи аргументов функции. Это будет работать до тех пор пока в программе не появится функция у которой общий размер аргументов будет превышать 8 байт.
Ну это наверное не ко мне а к Joerg Wunsch ? biggrin.gif
приведу Вам полный файл C:\WinAVR-20080512\doc\avr-libc\examples\asmdemo\project.h
Код
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Joerg Wunsch wrote this file.  As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.        Joerg Wunsch
* ----------------------------------------------------------------------------
*
* Demo combining C and assembly source files.
*
* $Id: project.h,v 1.1 2006/08/29 19:45:06 joerg_wunsch Exp $
*/

/*
* Global register variables.
*/
#ifdef __ASSEMBLER__

#  define sreg_save    r2
#  define flags        r16
#  define counter_hi    r4

#else  /* !ASSEMBLER */

#include <stdint.h>

register uint8_t sreg_save asm("r2");
register uint8_t flags     asm("r16");
register uint8_t counter_hi asm("r4");

#endif /* ASSEMBLER */
Просто сами его проверьте...
Цитата
They "don't work as you might wish" because at the RTL level a global
register variable is stored as a REG, and there is no way to mark a
REG as volatile.
Но факт то на лицо.... просто возмите и скомпилируйте сами...
иначе разговор очень странный, типа "это не может быть потому что не может быть..."
Ну меняет наличие volatile поведение у регистровой переменной и все тут...
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 11 2008, 22:08
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(singlskv @ Jun 12 2008, 01:15) *
а нафига они тогда вобще нужны smile.gif

Мое мнение их не надо использовать. Если регистровые переменые работают сегодня в коде из 50 строк, то нет ни какой гарантии что они будут работать когда размер проекта увеличется до 1000 строк.

Цитата
Это все понятно, действительно для long long, float и др библиотек можно нарваться,
Ну а если все это не используется ?

Все ваши функции не более 10 строк длиной? Вы точно знаете что компилятор не понаделает инлайн вставок и не превратит десяток таких функций в одну большую?

Цитата
Ну это наверное не ко мне а к Joerg Wunsch ? biggrin.gif

Насколько я понял он использовал r16 для flags для того чтобы написать в isrs.S:
Код
...
     ser    flags
...


Цитата
Просто сами его проверьте...

Это рабочий пример, только он рабочий до тех пор пока в него не добавили функцию
Код
void foo (long a, long b, char c);


Цитата
иначе разговор очень странный, типа "это не может быть потому что не может быть..."
Ну меняет наличие volatile поведение у регистровой переменной и все тут...

Меня не интерисует конкретный пример который случайно работает. В письме же написано регистровая переменая распологаеться в регистре. Регистр в GCC не имеет атрибута volatile, поэтому оптимизатор может оптимизировать доступ к этому регистру, тоесть переменной. Нельзя пологаться на volatile для регистровой переменной.
Анатолий.



Цитата(singlskv @ Jun 12 2008, 01:15) *
Ну меняет наличие volatile поведение у регистровой переменной и все тут...


Конечно меняет.
GCC при компиляции кода выполняет порядка 200 проходов, до какого-то времени
регистровая volatile переменная является volatile переменной и компилятор не
оптимизирует к ней доступ, но в какой то момент она превращается в регистр, к
сожалению без атрибута волативности, и вот тут возможна нежелательная
оптимизация.

Анатолий.

Сообщение отредактировал aesok - Jun 11 2008, 22:11
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- A.l.e.x.   Winavr сокращает функцию   Jun 10 2008, 11:54
||- - A.l.e.x.   Цитата(singlskv @ Jun 10 2008, 17:06) А к...   Jun 10 2008, 14:33
|||- - aesok   Цитата(singlskv @ Jun 11 2008, 23:23) Но ...   Jun 11 2008, 19:47
||||- - singlskv   Цитата(aesok @ Jun 11 2008, 23:47) GCC не...   Jun 11 2008, 20:13
|||- - singlskv   Цитата(aesok @ Jun 12 2008, 01:43) Все ва...   Jun 11 2008, 22:21
||- - alx2   Цитата(AHTOXA @ Jun 11 2008, 17:33) Стран...   Jun 12 2008, 11:50
||- - singlskv   Цитата(alx2 @ Jun 12 2008, 15:50) Я компи...   Jun 12 2008, 12:22
||- - alx2   Цитата(singlskv @ Jun 12 2008, 17:22) ИТО...   Jun 12 2008, 20:51
||- - aesok   сори, ошибочный пост   Jun 15 2008, 14:34
|- - singlskv   Цитата(A.l.e.x. @ Jun 10 2008, 16:36) И к...   Jun 10 2008, 13:59
|- - Сергей Борщ   Цитата(A.l.e.x. @ Jun 10 2008, 15:36) И к...   Jun 10 2008, 14:19
|- - A.l.e.x.   Цитата(Сергей Борщ @ Jun 10 2008, 17:19) ...   Jun 11 2008, 06:39
|- - Сергей Борщ   Цитата(A.l.e.x. @ Jun 11 2008, 09:39) Мож...   Jun 11 2008, 14:54
|- - A.l.e.x.   Цитата(Сергей Борщ @ Jun 11 2008, 17:54) ...   Jun 11 2008, 15:41
|- - Сергей Борщ   Цитата(A.l.e.x. @ Jun 11 2008, 18:41) Я и...   Jun 11 2008, 16:48
|- - A.l.e.x.   Цитата(Сергей Борщ @ Jun 11 2008, 19:48) ...   Jun 12 2008, 06:21
- - mdmitry   Разные версии WinAvr разрешают располагать регистр...   Jun 11 2008, 16:37
- - _Pasha   Тоже хотел недавно "поджать" компилер в ...   Jun 12 2008, 05:36
- - AHTOXA   Цитата(alx2 @ Jun 12 2008, 17:50) Я компи...   Jun 12 2008, 18:20
- - singlskv   Цитата(AHTOXA @ Jun 12 2008, 22:20) А я к...   Jun 12 2008, 19:04


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

 


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


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