On Nov. 11, 2001, I sent in a C51 V6.20 bug report via e-mail to support.us@keil.com. I never received a response, so assumed Keil's policy was to silently introduce the bug fix in a subsequent update. After downloading V6.21, I see that the bug is still present. Now I'm wondering whether my e-mailed bug report was ever acted upon, so I'm going to try the forum as the means to report the bug. I have a section of code with pointer incrementation that compiles and executes correctly when the pointer is defined as a generic pointer or as an xdata pointer, or when the optimization setting is reduced from the default OT(8,SPEED) to OT(7,SPEED). However, when the pointer is defined as a data or idata pointer, the compiler does not emit code to increment the pointer with default optimization. I have provided example code demonstrating the problem. The specific statement is line 50 below.
unsigned char idata u64[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; unsigned char idata s[21]; void U64ToStr( char idata *s, unsigned char idata *binP, unsigned char n ) { unsigned char bcd; unsigned char idata *bcdP; unsigned char bitMsk = 0x80; unsigned char carry; unsigned char i; /* Zero the target buffer (NUL-terminating the string). */ for (bcdP = s, i = n + 1; i != 0; *bcdP++ = 0, i--) ; /* Convert 64 bits of binary to unpacked BCD. For each bit, starting * with the MSBit, BCD = (BCD * 2) + bit. */ for (i = 64; i != 0; i--) { carry = (*binP & bitMsk) ? 1 : 0; for (bcdP = s + n; bcdP != s; /* Iter in body */) { bcd = *--bcdP * 2; bcd += carry; if (bcd < 10) carry = 0; else { carry = 1; bcd -= 10; } *bcdP = bcd; } if ((bitMsk >>= 1) == 0) { bitMsk = 0x80; binP++; } } /* ASCII'fy BCD. */ for (i = n; i != 0; i--) *bcdP++ += '0'; /* <-- C51 BUG: bcdP doesn't increment for (i)data */ } void main( void ) { for (;;) U64ToStr( s, u64, 6 ); }
It's not a bug, its a great optimization. Think about, does anyone one look at bcdP after this loop? No. So why emit code to update this variable? To better understand this add
i = *bcdP;
Huh??? Great optimization? So you are suggesting that rather than adding '0' (0x30) to ASCII'fy the first 6 digits in my string like I want, it's OK for the compiler to emit code that adds '0' 6 times to only first digit? I don't understand.
The ptr variable is store in a register and that is incremented.
The ptr variable is store in a register and that is incremented. Right and wrong. Jon, you really must try it to see. Here's an excerpt from the compiled code:
; SOURCE LINE # 15 ;---- Variable 'bcdP' assigned to Register 'R5' ---- ;=== MOST CODE SNIPPED === ; SOURCE LINE # 50 0063 AC01 MOV R4,AR1 0065 ?C0014: 0065 EC MOV A,R4 0066 600B JZ ?C0017 ; SOURCE LINE # 51 0068 AF05 MOV R7,AR5 006A A807 MOV R0,AR7 006C 7430 MOV A,#030H 006E 26 ADD A,@R0 006F F6 MOV @R0,A 0070 1C DEC R4 0071 80F2 SJMP ?C0014
Sorry, the file that I copied the code to compile had a optimization setting different than the project. I now get the same results as you.
Hey, no problem. Thanks for your consideration in even looking at the problem. You just had me sweatin' there for a little while. I would be embarassed to submit a false alarm. I just hope the report gets seen this time, since e-mailing it is (apparently) the wrong means. Thanks again, --Dan Henry