|
Winavr сокращает функцию, если переменные размещены в регистрах |
|
|
|
Jun 10 2008, 11:54
|
Участник

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

|
Помогите разобраться с WINAVR. При размещении переменных в регистрах компилятор ведёт себя подозрительно: сокращает функции, в которых они используются.  Но при обычном объявлении всё работает. Подскажите, где может быть ошибка? Код #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; } }
|
|
|
|
|
 |
Ответов
|
Jun 10 2008, 12:15
|
Знающий
   
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 10 2008, 12:36
|
Участник

Группа: Свой
Сообщений: 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?
|
|
|
|
|
Jun 10 2008, 14:02
|
Участник

Группа: Свой
Сообщений: 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 при объявлении регистровой переменной, все должно скомпилится правильно. Скомпилировалось, но не правильно. Можете сами проверить, в архиве весь проект...
|
|
|
|
|
Jun 10 2008, 16:28
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(singlskv @ Jun 10 2008, 18:06)  А какая версия WinAVR ? Все версии avr-gcc так работают. Анатолий.
|
|
|
|
|
Jun 10 2008, 17:44
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aesok @ Jun 10 2008, 20:28)  Все версии avr-gcc так работают. Ну это как минимум не так  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 ???
|
|
|
|
|
Jun 10 2008, 18:12
|

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

|
Цитата(singlskv @ Jun 10 2008, 23:44)  Можно ли получить такой же компактный/быстрый код на Gcc 4.x.x ??? Увы Без оптимизации выходит: Код 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).
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 10 2008, 19:32
|

Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 11 2008, 12:33
|

фанат дивана
     
Группа: Свой
Сообщений: 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? Хочу такой же
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jun 11 2008, 18:48
|
дятел
    
Группа: Свой
Сообщений: 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 А вот это не совсем так, оно не игнорируется целиком, но логика работы при этом мягко говоря странная...  результат при компиляции прерывания: 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 ВООБЩЕ У ДРУГОЙ ПЕРЕМЕННОЙ !
|
|
|
|
|
Jun 11 2008, 19:33
|
дятел
    
Группа: Свой
Сообщений: 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 ?
|
|
|
|
|
Jun 11 2008, 20:57
|
Знающий
   
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 11 2008, 21:15
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(aesok @ Jun 12 2008, 00:39)  Только если они не используются в прерываниях. а нафига они тогда вобще нужны  Цитата Во первых безопасно можно использовать только регистры r2-r7, остальные могут использоваться компилятором. Да именно так и написанно в доке, но для обсуждаймого примера это не существенно. Цитата Во вторых почему нельзя использовать глобальные регистровые переменные в обработчиках прерываний. ............................................... Это все понятно, действительно для long long, float и др библиотек можно нарваться, Ну а если все это не используется ? Цитата(aesok @ Jun 12 2008, 00:57)  Чюш!!!! r16 используется для передачи аргументов функции. Это будет работать до тех пор пока в программе не появится функция у которой общий размер аргументов будет превышать 8 байт. Ну это наверное не ко мне а к Joerg Wunsch ?  приведу Вам полный файл 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 поведение у регистровой переменной и все тут...
|
|
|
|
|
Jun 11 2008, 22:08
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(singlskv @ Jun 12 2008, 01:15)  а нафига они тогда вобще нужны  Мое мнение их не надо использовать. Если регистровые переменые работают сегодня в коде из 50 строк, то нет ни какой гарантии что они будут работать когда размер проекта увеличется до 1000 строк. Цитата Это все понятно, действительно для long long, float и др библиотек можно нарваться, Ну а если все это не используется ? Все ваши функции не более 10 строк длиной? Вы точно знаете что компилятор не понаделает инлайн вставок и не превратит десяток таких функций в одну большую? Цитата Ну это наверное не ко мне а к Joerg Wunsch ?  Насколько я понял он использовал 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
|
|
|
|
Сообщений в этой теме
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|