RE: [AVR-Chat] gcc compiler bad behaviour
2012-04-16 by Tim Mitchell
OK Thanks for the clarifications about volatile... what I was distracted by was that the variable in question was not being *changed* by an interrupt routine, it was only changed in mainline code. However it was being *read* in an interrupt routine. As the compiler couldn't see the variable being used in the current scope it optimised the code out. However - the strange thing is why the compiler has only optimised part of it, it is still loading the value into a register, but then has removed the store instruction. If it had optimised the whole thing away it would seem a slightly more valid thing to do.
Show quoted textHide quoted text
----Original Message----
From: AVR-Chat@yahoogroups.com
[mailto:AVR-Chat@yahoogroups.com] On Behalf Of Tim Mitchell
Sent: 13 April 2012 11:35 To: AVR-Chat@yahoogroups.com
Subject: [AVR-Chat] gcc compiler bad behaviour
> The GCC compiler optimiser seems to be doing a weird
> thing to me... I'd like to understand it. it seems to
> require a volatile qualifier when I am not expecting it.
>
> I have the following variables defined
> unsigned char LedLevel0=0;
> unsigned char LedLevel1=0;
> volatile unsigned char AdcVal[4];
>
> AdcVal holds readings from the ADC and is loaded in an
> interrupt routine
>
> main loop:
>
> //the main loop
> while(1)
> {
> LedLevel0=AdcVal[0];
> LedLevel1=AdcVal[1];
> }
>
> compiler output:
>
> //the main loop
> while(1)
> {
> LedLevel0=AdcVal[0];
> 3ea: 80 91 86 01 lds r24, 0x0186
> LedLevel1=AdcVal[1];
> 3ee: 80 91 87 01 lds r24, 0x0187
> 3f2: fb cf rjmp .-10 ; 0x3ea <main+0x8>
>
> i.e. it's loading the AdcVal into r24, but never stores
> it into the other variable.
>
> if I change the main loop to add a call to a delay
> routine then it works correctly. Also if I declare
> LedLevel0/1 as volatile.
> But in my mind it shouldn't need to be declared volatile,
> nothing else is changing it.
>
> //the main loop
> while(1)
> {
> LedLevel0=AdcVal[0];
> LedLevel1=AdcVal[1];
> TimeWait(1);
> }
>
> compiler output:
> //the main loop
> while(1)
> {
> LedLevel0=AdcVal[0];
> 3ea: 80 91 86 01 lds r24, 0x0186
> 3ee: 80 93 06 01 sts 0x0106, r24
> LedLevel1=AdcVal[1];
> 3f2: 80 91 87 01 lds r24, 0x0187
> 3f6: 80 93 07 01 sts 0x0107, r24
> TimeWait(1);
> 3fa: 81 e0 ldi r24, 0x01 ; 1
> 3fc: 90 e0 ldi r25, 0x00 ; 0
> 3fe: f4 cf rjmp .-24 ; 0x3e8 <main+0x6>
--
Tim Mitchell