Mon 07 Mar 2005 11:27:29 PM UTC, original submission:
Hallo
I am quite sure to have a problem with a specific loop where an array is filled with the loops variable value. The array is found to be filled backwards with the decending instead of accending value and also writes are made over the end of the array.
Please accept the following description which I posted a couple of days ago in the yahoo gnu-m68hc11 group. I checked to see whether this case has maybe already reported but didn't see anything obvious - please accept appologies if already reported / fixed.
Regards
Mark Butcher
-unavailable-
////////////////////////////////////////////////////////
Hi All
I wonder whether I have found a bug in the compiler?
The compiler version is:
Thread model: single
gcc version 3.3.4-m68hc1x-20040829
The code which I have written is:
static unsigned char spi_test1[256];
void fnTest(void)
{
unsigned short i;
for (i=0; i < sizeof(spi_test1); i++) {
spi_test1[i] = (unsigned char)i;
}
}
The result which I obtain is that the array spi_test1[] is
initialised but not as expected. I expect it to be initialised as
follows:
spi_test1[0] = 0;
spi_test1[1] = 1;
spi_test1[2] = 2;
...
spi_test1[255] = 255;
The results which I get is
spi_test1[0] = 0; // I think this was not set as it was 0 by default
spi_test1[1] = 255;
spi_test1[2] = 254;
...
spi_test1[255] = 1;
spi_test1[256] = 0; // !! 256 doesn't exit so a write is made after
end of buffer
That is BACKWARDS...As can be seen it actually also overwrites data
after the end of the array....
I had a look at the generated assembler code which is as follows:
0xc187 [ce 00 00] LDX #0000
0xc18A [1b 86] LEAS 6,SP
0xc18C [cc 01 00] LDD #0x0100
0xc18F [b7 c5] EXG D,X
0xc191 [6b e2 31 42] STAB 3142,X // first time around
saves spi_test[0x100] with 0x00 (writes after end of array),
// then spi_test[0xff]
with 0xff, etc.
0xc195 [b7 c5] EXG D,X
0xc197 [08] INX
0xc198 [04 34 f4] DBNE D,-C
Then I tried this code:
static unsigned char spi_test1[256];
void fnTest(void)
{
unsigned short i;
unsigned short j = 0;
for (i=0; i < sizeof(spi_test1); i++) {
spi_test1[j++] = (unsigned char)j;
}
}
but the produced assembler code was identical.
The problem was cured only when the following code was used:
static unsigned char spi_test1[256];
void fnTest(void)
{
unsigned short i;
unsigned char j = 0; // unsigned char rather that unsigned
short
for (i=0; i < sizeof(spi_test1); i++) {
spi_test1[j++] = j;
}
}
This is the assembler code which then worked properly (it is quite a
bit longer..):
0xc189 [fd 31 2c] LDY 312c
0xc18C [69 e8 70] CLR 70,Y
0xc18F [1b 86] LEAS 6,SP
0xc191 [ce 01 00] LDX #0100
0xc194 [7e 31 28] STX 3128
0xc197 [ce 31 42] LDX #3142
0xc19A [fd 31 2c] LDY 312c
0xc19D [e6 e8 70] LDAB 70,Y
0xc1A0 [1a e5] LEAX B,X
0xc1A2 [6b 00] STAB 0,X
0xc1A4 [52] INCB
0xc1A5 [6b e8 70] STAB 70,Y
0xc1A8 [fe 31 28] LDX 3128
0xc1AB [09] DEX
0xc1AC [7e 31 28] STX 3128
0xc1AF [26 e6] BNE -1A
Can anyone confirm this or explain why it happens?
regards
Mark Butcher
http://www.mjbc.ch
////////////////////////////////////////////////////
|