This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C51 Compiler Bug, Help Please !

I catch a C51 compiler bug when debugging some functions to calculate time differrence.
The main function's prints out shows that function DifferExStamp(T1,T2) give error time differrence, but DifferJDxTime(djT1,djT2) give correct results.
When I check into disassembly code in uvision IDE, i can see that the "data overlaying" for function DifferExStamp(...) -> DifferJDxTime(...) is incorrect, leading the argument djT1 (a return value) be destroyed by the function call to calculate djT2.

The C51 compiler version is 7.08, code optimization level is 8.

The codes are attached below.

Is the Compiler wrong, or my wrong ?
Please Help me. Thanks.

//==========================================================

#include <reg52.h>		// special function register 8052
#endif
#include <stdio.h>
#include <stdlib.h>  /* For randomize function */

typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long ULONG;
typedef bit BOOL;

typedef struct tagExDate
{
	BYTE cCent;
	BYTE cYear;
	BYTE cMon;
	BYTE cDay;
} CExDate;

typedef struct tagExTime
{
	BYTE cHour;
	BYTE cMin;
	BYTE cSec;
	BYTE cX100ms;
} CExTime;

typedef struct tagExStamp
{
	CExDate Date;
	CExTime	Time;
} CExStamp;

typedef struct tagJDxTime
{
	long lDays;
	ULONG dwX100ms;
} CJDxTime;

CJDxTime ExStampToJDxTime(CExStamp oExT1);
CExStamp JDxTimeToExStamp(CJDxTime oJDxT1);

CJDxTime DifferExStamp(CExStamp oExT1, CExStamp oExT2);
CJDxTime DifferJDxTime(CJDxTime oJDxT1, CJDxTime oJDxT2);

BOOL IsBadExStamp(CExStamp oExT);

void ExStampToString(CExStamp oExTime, char *szTime);

#define SECONDS_PER_MINUTE (60)
#define SECONDS_PER_HOUR (60*60)
#define SECONDS_PER_DAY (24*60*60L)

#define BAUD9600_TH1	0xFA    /*9600 BAUD in 22.1184MHz.T1@Mode2,bit SMOD=0.*/
#define BAUD_TH1 BAUD9600_TH1

void main(void)
{
	CExStamp xdata n_oExT1, xdata n_oExT2, xdata n_oNewExT;
	CJDxTime xdata n_oJDxT1, xdata n_oJDxT2, xdata n_oNewJDxT, xdata n_oJDxDletaT;
	BYTE xdata n_szBuf[32];
	char cResult;

	TMOD = (TMOD & 0x0F) | 0x20;

	TH1=BAUD_TH1;			/*Setup initial baudrate.*/
	TL1=BAUD_TH1;

	SCON = 0x52;			/*(0x52) initialize UART to mode 1   */

	TR1 = 1;				//	Open T1 as baudrate generator

	printf("Please Input 1 Date (as 1902-03-22):");
	scanf("%2bd%2bd-%2bd-%2bd",&n_oExT1.Date.cCent,&n_oExT1.Date.cYear, &n_oExT1.Date.cMon,&n_oExT1.Date.cDay);
	printf("\nPlease Input 1 Time (as 20:02:23.4):");
	scanf("%2bd:%2bd:%2bd.%1bd",&n_oExT1.Time.cHour,&n_oExT1.Time.cMin,&n_oExT1.Time.cSec,&n_oExT1.Time.cX100ms);

	if (IsBadExStamp(n_oExT1))
	{
		printf("\nYou Input a BAD DateTime !\n");
		return;
	}
	else
	{
		ExStampToString(n_oExT1,n_szBuf);
		printf("\nYou Input a GOOD DateTime:%s,",n_szBuf);

		n_oJDxT1 = ExStampToJDxTime(n_oExT1);
		printf("\nThe DaysTime is:%ld-%lu. ",n_oJDxT1.lDays,n_oJDxT1.dwX100ms);
	}

	printf("Please Input 2 Date (as 1902-03-22):");
	scanf("%2bd%2bd-%2bd-%2bd",&n_oExT2.Date.cCent,&n_oExT2.Date.cYear,	&n_oExT2.Date.cMon,&n_oExT2.Date.cDay);
	printf("\nPlease Input 2 Time (as 20:02:23.5):");
	scanf("%2bd:%2bd:%2bd.%1bd",&n_oExT2.Time.cHour,&n_oExT2.Time.cMin,&n_oExT2.Time.cSec,&n_oExT2.Time.cX100ms);

	if (IsBadExStamp(n_oExT2))
	{
		printf("\nYou Input a BAD DateTime !\n");
		return;
	}
	else
	{
		ExStampToString(n_oExT2,n_szBuf);
		printf("\nYou Input a GOOD DateTime:%s, ",n_szBuf);

		n_oJDxT2 = ExStampToJDxTime(n_oExT2);
		printf("\nThe DaysTime is:%ld-%lu. ",n_oJDxT2.lDays,n_oJDxT2.dwX100ms);
	}

	//====return error "difference time" !!!=============
	n_oJDxDletaT = DifferExStamp(n_oExT1, n_oExT2);
	printf("\nThe Difference DateTime (T1-T2) is:%ld-%lu.\n",n_oJDxDletaT.lDays,n_oJDxDletaT.dwX100ms);
	//
	//====return correct "difference time" !!!=============
	n_oJDxDletaT = DifferJDxTime(n_oJDxT1, n_oJDxT2);
	printf("The Difference DaysTime (T1-T2) is:%ld-%lu.\n",n_oJDxDletaT.lDays,n_oJDxDletaT.dwX100ms);
}

CJDxTime ExStampToJDxTime(CExStamp oExT1)
{
	CJDxTime n_oJDxTime;

	oExT1.Date.cMon = (oExT1.Date.cMon + 9)%12;

#define wYear *((WORD*)&(n_oJDxTime.dwX100ms))
	wYear = (WORD)oExT1.Date.cCent*100 + oExT1.Date.cYear;
	if (oExT1.Date.cMon/10)
	{
		wYear -= 1;
	}

	n_oJDxTime.lDays = (ULONG)wYear*365L + wYear/4 - wYear/100 + wYear/400 + (oExT1.Date.cMon*306 + 5)/10 + (oExT1.Date.cDay - 1);
#undef wYear

	n_oJDxTime.dwX100ms = (ULONG)oExT1.Time.cHour*((ULONG)SECONDS_PER_HOUR*10)

+(WORD)oExT1.Time.cMin*((WORD)SECONDS_PER_MINUTE*10) +(WORD)oExT1.Time.cSec*10 +oExT1.Time.cX100ms;

	return n_oJDxTime;
}

CJDxTime DifferExStamp(CExStamp oExT1, CExStamp oExT2)
{
	//===Data overlay improperly !!!
	return DifferJDxTime((ExStampToJDxTime(oExT1)),(ExStampToJDxTime(oExT2)));
}

CJDxTime DifferJDxTime(CJDxTime oJDxT1, CJDxTime oJDxT2)
{
	if (oJDxT1.dwX100ms < oJDxT2.dwX100ms)
	{
		oJDxT1.lDays --;
		oJDxT1.dwX100ms += (ULONG)SECONDS_PER_DAY*10L;
	}

	oJDxT1.dwX100ms -= oJDxT2.dwX100ms ;
	oJDxT1.lDays -= oJDxT2.lDays ;

	return oJDxT1;
}

BOOL IsBadExStamp(CExStamp oExT)
{
	if ((oExT.Time.cSec > 59) || (oExT.Time.cMin > 59) || (oExT.Time.cHour > 23)
		|| (oExT.Date.cCent < 19) || (oExT.Date.cCent > 99) || (oExT.Date.cYear > 99)
		|| (oExT.Date.cMon == 0) || (oExT.Date.cMon > 12)
		|| (oExT.Date.cDay == 0) || (oExT.Date.cDay > 31))
		return 1;

	return 0;
}

void ExStampToString(CExStamp oExTime, char *szTime)
{
	sprintf(szTime,"%02bd%02bd-%02bd-%02bd %02bd:%02bd:%02bd.%1bd",oExTime.Date.cCent,oExTime.Date.cYear,
		oExTime.Date.cMon,oExTime.Date.cDay,oExTime.Time.cHour,oExTime.Time.cMin,oExTime.Time.cSec,oExTime.Time.cX100ms);
}

Parents
  • Hi, Broeker. Thanks.

    On debugging, i met the problem in the implementation of function DifferExStamp(). The assembly code lines of function DifferDJxTime() seem good.

    The following are the relevant *.lst fragments.

    Best regards.

     155          CJDxTime DifferExStamp(CExStamp oExT1, CExStamp oExT2)
     156          {
     157   1              //===Data overlay improperly !!!
     158   1              return DifferJDxTime((ExStampToJDxTime(oExT1)),(ExStampToJDxTime(oExT2)));
     159   1      }
     160
     161          CJDxTime DifferJDxTime(CJDxTime oJDxT1, CJDxTime oJDxT2)
     162          {
     163   1              if (oJDxT1.dwX100ms < oJDxT2.dwX100ms)
     164   1              {
     165   2                      oJDxT1.lDays --;
     166   2                      oJDxT1.dwX100ms += (ULONG)SECONDS_PER_DAY*10L;
     167   2              }
     168   1
     169   1              oJDxT1.dwX100ms -= oJDxT2.dwX100ms ;
     170   1              oJDxT1.lDays -= oJDxT2.lDays ;
    
     171   1
     172   1              return oJDxT1;
     173   1      }
     174
    
                 ; FUNCTION DifferExStamp (BEGIN)
                                               ; SOURCE LINE # 155
                                               ; SOURCE LINE # 156
                                               ; SOURCE LINE # 158
    0000 7800        R     MOV     R0,#LOW ?ExStampToJDxTime?BYTE
    0002 7C00        R     MOV     R4,#HIGH ?ExStampToJDxTime?BYTE
    0004 7D00              MOV     R5,#00H
    0006 7B00              MOV     R3,#00H
    0008 7A00        R     MOV     R2,#HIGH oExT1
    000A 7900        R     MOV     R1,#LOW oExT1
    000C 120000      R     LCALL   L?0020
    000F 7800        R     MOV     R0,#LOW ?DifferJDxTime?BYTE
    0011 7C00        R     MOV     R4,#HIGH ?DifferJDxTime?BYTE
    0013 7D00              MOV     R5,#00H
    0015 7E00              MOV     R6,#00H
    0017 7F08              MOV     R7,#08H
    0019 120000      E     LCALL   ?C?COPY
    001C 7800        R     MOV     R0,#LOW ?ExStampToJDxTime?BYTE
    001E 7C00        R     MOV     R4,#HIGH ?ExStampToJDxTime?BYTE
    0020 7D00              MOV     R5,#00H
    0022 7B00              MOV     R3,#00H
    0024 7A00        R     MOV     R2,#HIGH oExT2
    0026 7900        R     MOV     R1,#LOW oExT2
    0028 120000      R     LCALL   L?0020
    002B 7800        R     MOV     R0,#LOW ?DifferJDxTime?BYTE+08H
    002D 7C00        R     MOV     R4,#HIGH ?DifferJDxTime?BYTE+08H
    002F 7D00              MOV     R5,#00H
    0031 120000      R     LCALL   L?0023
                                               ; SOURCE LINE # 159
    0034         ?C0008:
    0034 22                RET
    
                 ; FUNCTION DifferExStamp (END)
    
                 ; FUNCTION L?0023 (BEGIN)
    0000 7E00              MOV     R6,#00H
    0002 7F08              MOV     R7,#08H
    0004 120000      E     LCALL   ?C?COPY
                 ; FUNCTION DifferJDxTime (BEGIN)
                                               ; SOURCE LINE # 161
                                               ; SOURCE LINE # 162
                                               ; SOURCE LINE # 163
    0007 AF00        R     MOV     R7,oJDxT2+07H
    0009 AE00        R     MOV     R6,oJDxT2+06H
    000B AD00        R     MOV     R5,oJDxT2+05H
    000D AC00        R     MOV     R4,oJDxT2+04H
    000F AB00        R     MOV     R3,oJDxT1+07H
    0011 AA00        R     MOV     R2,oJDxT1+06H
    0013 A900        R     MOV     R1,oJDxT1+05H
    0015 A800        R     MOV     R0,oJDxT1+04H
    0017 C3                CLR     C
    0018 120000      E     LCALL   ?C?ULCMP
    001B 502E              JNC     ?C0009
                                               ; SOURCE LINE # 164
                                               ; SOURCE LINE # 165
    001D 74FF              MOV     A,#0FFH
    001F 2500        R     ADD     A,oJDxT1+03H
    0021 F500        R     MOV     oJDxT1+03H,A
    0023 E500        R     MOV     A,oJDxT1+02H
    0025 34FF              ADDC    A,#0FFH
    0027 F500        R     MOV     oJDxT1+02H,A
    0029 E500        R     MOV     A,oJDxT1+01H
    002B 34FF              ADDC    A,#0FFH
    002D F500        R     MOV     oJDxT1+01H,A
    002F E500        R     MOV     A,oJDxT1
    0031 34FF              ADDC    A,#0FFH
    0033 F500        R     MOV     oJDxT1,A
                                               ; SOURCE LINE # 166
    0035 E4                CLR     A
    0036 2500        R     ADD     A,oJDxT1+07H
    0038 F500        R     MOV     oJDxT1+07H,A
    003A E500        R     MOV     A,oJDxT1+06H
    003C 342F              ADDC    A,#02FH
    003E F500        R     MOV     oJDxT1+06H,A
    0040 E500        R     MOV     A,oJDxT1+05H
    0042 340D              ADDC    A,#0DH
    0044 F500        R     MOV     oJDxT1+05H,A
    0046 E4                CLR     A
    0047 3500        R     ADDC    A,oJDxT1+04H
    0049 F500        R     MOV     oJDxT1+04H,A
                                               ; SOURCE LINE # 167
    004B         ?C0009:
                                               ; SOURCE LINE # 169
    004B C3                CLR     C
    004C E500        R     MOV     A,oJDxT1+07H
    004E 9500        R     SUBB    A,oJDxT2+07H
    0050 F500        R     MOV     oJDxT1+07H,A
    0052 E500        R     MOV     A,oJDxT1+06H
    0054 9500        R     SUBB    A,oJDxT2+06H
    0056 F500        R     MOV     oJDxT1+06H,A
    0058 E500        R     MOV     A,oJDxT1+05H
    005A 9500        R     SUBB    A,oJDxT2+05H
    005C F500        R     MOV     oJDxT1+05H,A
    005E E500        R     MOV     A,oJDxT1+04H
    
    0060 9500        R     SUBB    A,oJDxT2+04H
    0062 F500        R     MOV     oJDxT1+04H,A
                                               ; SOURCE LINE # 170
    0064 C3                CLR     C
    0065 E500        R     MOV     A,oJDxT1+03H
    0067 9500        R     SUBB    A,oJDxT2+03H
    0069 F500        R     MOV     oJDxT1+03H,A
    006B E500        R     MOV     A,oJDxT1+02H
    006D 9500        R     SUBB    A,oJDxT2+02H
    006F F500        R     MOV     oJDxT1+02H,A
    0071 E500        R     MOV     A,oJDxT1+01H
    0073 9500        R     SUBB    A,oJDxT2+01H
    0075 F500        R     MOV     oJDxT1+01H,A
    0077 E500        R     MOV     A,oJDxT1
    0079 9500        R     SUBB    A,oJDxT2
    007B F500        R     MOV     oJDxT1,A
                                               ; SOURCE LINE # 172
    007D 7B00              MOV     R3,#00H
    007F 7A00        R     MOV     R2,#HIGH oJDxT1
    0081 7900        R     MOV     R1,#LOW oJDxT1
                                               ; SOURCE LINE # 173
    0083         ?C0010:
    0083 22                RET
                 ; FUNCTION DifferJDxTime (END)
    

Reply
  • Hi, Broeker. Thanks.

    On debugging, i met the problem in the implementation of function DifferExStamp(). The assembly code lines of function DifferDJxTime() seem good.

    The following are the relevant *.lst fragments.

    Best regards.

     155          CJDxTime DifferExStamp(CExStamp oExT1, CExStamp oExT2)
     156          {
     157   1              //===Data overlay improperly !!!
     158   1              return DifferJDxTime((ExStampToJDxTime(oExT1)),(ExStampToJDxTime(oExT2)));
     159   1      }
     160
     161          CJDxTime DifferJDxTime(CJDxTime oJDxT1, CJDxTime oJDxT2)
     162          {
     163   1              if (oJDxT1.dwX100ms < oJDxT2.dwX100ms)
     164   1              {
     165   2                      oJDxT1.lDays --;
     166   2                      oJDxT1.dwX100ms += (ULONG)SECONDS_PER_DAY*10L;
     167   2              }
     168   1
     169   1              oJDxT1.dwX100ms -= oJDxT2.dwX100ms ;
     170   1              oJDxT1.lDays -= oJDxT2.lDays ;
    
     171   1
     172   1              return oJDxT1;
     173   1      }
     174
    
                 ; FUNCTION DifferExStamp (BEGIN)
                                               ; SOURCE LINE # 155
                                               ; SOURCE LINE # 156
                                               ; SOURCE LINE # 158
    0000 7800        R     MOV     R0,#LOW ?ExStampToJDxTime?BYTE
    0002 7C00        R     MOV     R4,#HIGH ?ExStampToJDxTime?BYTE
    0004 7D00              MOV     R5,#00H
    0006 7B00              MOV     R3,#00H
    0008 7A00        R     MOV     R2,#HIGH oExT1
    000A 7900        R     MOV     R1,#LOW oExT1
    000C 120000      R     LCALL   L?0020
    000F 7800        R     MOV     R0,#LOW ?DifferJDxTime?BYTE
    0011 7C00        R     MOV     R4,#HIGH ?DifferJDxTime?BYTE
    0013 7D00              MOV     R5,#00H
    0015 7E00              MOV     R6,#00H
    0017 7F08              MOV     R7,#08H
    0019 120000      E     LCALL   ?C?COPY
    001C 7800        R     MOV     R0,#LOW ?ExStampToJDxTime?BYTE
    001E 7C00        R     MOV     R4,#HIGH ?ExStampToJDxTime?BYTE
    0020 7D00              MOV     R5,#00H
    0022 7B00              MOV     R3,#00H
    0024 7A00        R     MOV     R2,#HIGH oExT2
    0026 7900        R     MOV     R1,#LOW oExT2
    0028 120000      R     LCALL   L?0020
    002B 7800        R     MOV     R0,#LOW ?DifferJDxTime?BYTE+08H
    002D 7C00        R     MOV     R4,#HIGH ?DifferJDxTime?BYTE+08H
    002F 7D00              MOV     R5,#00H
    0031 120000      R     LCALL   L?0023
                                               ; SOURCE LINE # 159
    0034         ?C0008:
    0034 22                RET
    
                 ; FUNCTION DifferExStamp (END)
    
                 ; FUNCTION L?0023 (BEGIN)
    0000 7E00              MOV     R6,#00H
    0002 7F08              MOV     R7,#08H
    0004 120000      E     LCALL   ?C?COPY
                 ; FUNCTION DifferJDxTime (BEGIN)
                                               ; SOURCE LINE # 161
                                               ; SOURCE LINE # 162
                                               ; SOURCE LINE # 163
    0007 AF00        R     MOV     R7,oJDxT2+07H
    0009 AE00        R     MOV     R6,oJDxT2+06H
    000B AD00        R     MOV     R5,oJDxT2+05H
    000D AC00        R     MOV     R4,oJDxT2+04H
    000F AB00        R     MOV     R3,oJDxT1+07H
    0011 AA00        R     MOV     R2,oJDxT1+06H
    0013 A900        R     MOV     R1,oJDxT1+05H
    0015 A800        R     MOV     R0,oJDxT1+04H
    0017 C3                CLR     C
    0018 120000      E     LCALL   ?C?ULCMP
    001B 502E              JNC     ?C0009
                                               ; SOURCE LINE # 164
                                               ; SOURCE LINE # 165
    001D 74FF              MOV     A,#0FFH
    001F 2500        R     ADD     A,oJDxT1+03H
    0021 F500        R     MOV     oJDxT1+03H,A
    0023 E500        R     MOV     A,oJDxT1+02H
    0025 34FF              ADDC    A,#0FFH
    0027 F500        R     MOV     oJDxT1+02H,A
    0029 E500        R     MOV     A,oJDxT1+01H
    002B 34FF              ADDC    A,#0FFH
    002D F500        R     MOV     oJDxT1+01H,A
    002F E500        R     MOV     A,oJDxT1
    0031 34FF              ADDC    A,#0FFH
    0033 F500        R     MOV     oJDxT1,A
                                               ; SOURCE LINE # 166
    0035 E4                CLR     A
    0036 2500        R     ADD     A,oJDxT1+07H
    0038 F500        R     MOV     oJDxT1+07H,A
    003A E500        R     MOV     A,oJDxT1+06H
    003C 342F              ADDC    A,#02FH
    003E F500        R     MOV     oJDxT1+06H,A
    0040 E500        R     MOV     A,oJDxT1+05H
    0042 340D              ADDC    A,#0DH
    0044 F500        R     MOV     oJDxT1+05H,A
    0046 E4                CLR     A
    0047 3500        R     ADDC    A,oJDxT1+04H
    0049 F500        R     MOV     oJDxT1+04H,A
                                               ; SOURCE LINE # 167
    004B         ?C0009:
                                               ; SOURCE LINE # 169
    004B C3                CLR     C
    004C E500        R     MOV     A,oJDxT1+07H
    004E 9500        R     SUBB    A,oJDxT2+07H
    0050 F500        R     MOV     oJDxT1+07H,A
    0052 E500        R     MOV     A,oJDxT1+06H
    0054 9500        R     SUBB    A,oJDxT2+06H
    0056 F500        R     MOV     oJDxT1+06H,A
    0058 E500        R     MOV     A,oJDxT1+05H
    005A 9500        R     SUBB    A,oJDxT2+05H
    005C F500        R     MOV     oJDxT1+05H,A
    005E E500        R     MOV     A,oJDxT1+04H
    
    0060 9500        R     SUBB    A,oJDxT2+04H
    0062 F500        R     MOV     oJDxT1+04H,A
                                               ; SOURCE LINE # 170
    0064 C3                CLR     C
    0065 E500        R     MOV     A,oJDxT1+03H
    0067 9500        R     SUBB    A,oJDxT2+03H
    0069 F500        R     MOV     oJDxT1+03H,A
    006B E500        R     MOV     A,oJDxT1+02H
    006D 9500        R     SUBB    A,oJDxT2+02H
    006F F500        R     MOV     oJDxT1+02H,A
    0071 E500        R     MOV     A,oJDxT1+01H
    0073 9500        R     SUBB    A,oJDxT2+01H
    0075 F500        R     MOV     oJDxT1+01H,A
    0077 E500        R     MOV     A,oJDxT1
    0079 9500        R     SUBB    A,oJDxT2
    007B F500        R     MOV     oJDxT1,A
                                               ; SOURCE LINE # 172
    007D 7B00              MOV     R3,#00H
    007F 7A00        R     MOV     R2,#HIGH oJDxT1
    0081 7900        R     MOV     R1,#LOW oJDxT1
                                               ; SOURCE LINE # 173
    0083         ?C0010:
    0083 22                RET
                 ; FUNCTION DifferJDxTime (END)
    

Children
  • The actual problem is in the linker, then, and it's for real. I managed to reproduce it now. The parameters:

    * C51 7.09 (--> everything current)

    * optimization >=2 (data overlaying) triggers it.

    According to the map file, the data sections for ExStamptoJDxTime() and DifferJDxTime() are indeed overlayed, so the objects

    ?DifferJDxTime?BYTE
    ?ExStampToJDxTime?BYTE
    

    found in the posted *.lst excerpt end up both on the same address (032h at optimize 8). This means the set-up of oExT2 as the argument to the conversion function overwrites the result of the previous call which had been copied into the space for the first argument of DifferJDxTime().

    Maybe the overlay generator just can't cope with multi-byte return values that can't be held in registers.

    Anyway: I conclude you'll have to pass this over to Keil Support.

  • From your explanation, I'm quite clear on the problem now.

    Thank you very much.