[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] a newbie's question
From: |
TeeN |
Subject: |
Re: [avr-gcc-list] a newbie's question |
Date: |
Sat, 8 Jun 2002 10:30:58 +0800 |
On 7 Jun 2002 at 9:06, Bruce D. Lightner wrote:
> Dear ???:
>
> > Hi Guru,
> >
> > I have used the following CFLAGS to make the gcctest8.c:
> >
> > CFLAGS = -O1 -Wall -Wstrict-prototypes -Wa,-ahlms=$(<:.c=.lst)
> >
> > the original C code:
> >
> > for (j=0; j<255; j++)
> > k++;
> >
> > generates:
> >
> > ldi r24, 0 ; for (j=0;
> > loc_5F: ;
> > subi r24, -1 ; ;j++)
> > cpi r24, -1
> > brcs loc_5F ; r24 == 0x00-0xFE : loop
> > r24 == 0xFF : fall thru
> >
> > 1. k++ line is optimised. it is ok.
> > 2. since the "subi r24,0xFF" has increased r24 before the
> > comparision, the loop actually executed 253 times instead of 254
> > times.
> >
> > if i use -O3 to optimise it, the disassembled code is even funny. Is
> > it something wrong with my system ?
> > thanks!
>
> This is a common misunderstanding of "avr-gcc" and it's optimizer...
>
> You didn't provide the entire program, but I'll bet that you don't have "k"
> declared as:
>
> volatile int k;
>
> and "k" is not a returned parameter.
>
> If you do *not* declare "k" as volatile, then the "gcc" optimizer is free to
> do whatever it wants with your for-loop and what is inside it. What is
> usually does in this case seldom makes sense to us humans! :-)
>
> Best regards,
>
> Bruce
>
> P.S.- Next time provide the entire program...and your name! :-)
>
> --
> Bruce D. Lightner
> La Jolla, California
> Email: address@hidden
> URL: http://www.lightner.net/lightner/bruce/
Hi Bruce,
Thanks for you tips.
1. that was my first post to this mailing list so i have forgotten to leave my
name too :p
2. my question is not on the k++ line being optimised. My problem is on the for
loops.
Here i have included another code fragment below to show my problem. I would
appreciate if any guru can shed some lights on it.
C code:
typedef unsigned char u08;
u08 func1( void )
{
u08 i, j, k;
k = 0;
for (i=0; i<0xfe; i++) /* outer delay loop */
for(j=0; j<0xfe;j++) /* inner delay loop */
k++; /* just do something */
return k;
}
disassembled by avr-objdump -D
00000096 <func1>:
96: 80 e0 ldi r24, 0x00 ; k=0;
98: 98 2f mov r25, r24 ; for (i=0;
9a: 20 e0 ldi r18, 0x00 ; for (j=0;
9c: 8e 5f subi r24, 0xFE ; k += 0x02;
<--*1
9e: 2e 5f subi r18, 0xFE ; j += 0x02;
<--*2
a0: 2e 3f cpi r18, 0xFE ; if (j<0xfe) loop
<-*3
a2: e0 f3 brcs 0x9c
a4: 9f 5f subi r25, 0xFF ; i++;
a6: 9e 3f cpi r25, 0xFE ; if (i<0xfe) loop
<--*4
a8: c0 f3 brcs 0x9a
aa: 99 27 eor r25, r25
ac: 08 95 ret
problem *1: k++ is compiled to k += 0x02;
problem *2: j++ is compiled to j += 0x02;
problem *3 and *4: in the for (i=0; i<0xfe; i++) code, gcc compiled it into an
assembled code that first do the increment BEFORE the
comparision. This creates OBOB (off-by-one bug) -- the loop actually executed 1
time less than expected (assume that problem *1
and *2 is not taken into account).
In my last post, i quoted:
> > 2. since the "subi r24,0xFF" has increased r24 before the
> > comparision, the loop actually executed 253 times instead of 254
> > times.
It should be interpreted as:
>>2. since the "subi r24,0xFF" has increased r24 before the
>>omparision, the loop actually executed "254" times instead of "255"
>>times.
This is the OBOB I am talking about.
my gcc version is: 3.0.2
Any comment will be appreciated. Thanks!
TeeN (This time i remember to leave my name :)
_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com
avr-gcc-list at http://avr1.org