ARM Technical Support Knowledge Articles

COMPILER DOES NOT INITIALIZE R1/R2/R3 FOR ?C?CSTOPTR

Applies to: C51 C Compiler

Answer


Information in this article applies to:


SYMPTOMS

When indirectly dereferencing a typed pointer as a generic pointer, the C51 compiler may not properly initialize R1, R2, and R3 before calling the ?C?STOPTR library routine. For example, the following function:

unsigned char xdata DummyVariable;
unsigned char xdata Temp;

void TestFunction(void)
{
for(Temp=0;Temp<31;Temp++)
        {
                *(&DummyVariable + (Temp * Offset)) = 0;
        }
}

generates the following code:

             ; FUNCTION TestFunction (BEGIN)
                                           ; SOURCE LINE # 12
                                           ; SOURCE LINE # 13
                                           ; SOURCE LINE # 14
0000 E4                CLR     A
0001 900000      R     MOV     DPTR,#Temp
0004 F0                MOVX    @DPTR,A
0005         ?C0001:
0005 900000      R     MOV     DPTR,#Temp
0008 E0                MOVX    A,@DPTR
0009 FF                MOV     R7,A
000A C3                CLR     C
000B 941F              SUBB    A,#01FH
000D 501B              JNC     ?C0004
                                           ; SOURCE LINE # 15
                                           ; SOURCE LINE # 16
000F 75F003            MOV     B,#03H
0012 EF                MOV     A,R7
0013 A4                MUL     AB
0014 2400        R     ADD     A,#LOW DummyVariable
0016 F582              MOV     DPL,A
0018 E5F0              MOV     A,B
001A 3400        R     ADDC    A,#HIGH DummyVariable
001C F583              MOV     DPH,A
001E E4                CLR     A
001F 120000      E     LCALL   ?C?CSTOPTR
                                           ; SOURCE LINE # 17
0022 900000      R     MOV     DPTR,#Temp
0025 E0                MOVX    A,@DPTR
0026 04                INC     A
0027 F0                MOVX    @DPTR,A
0028 80DB              SJMP    ?C0001
                                           ; SOURCE LINE # 18
002A         ?C0004:
002A 22                RET
             ; FUNCTION TestFunction (END)

Note that R1, R2, and R3 are never initialized for this example.

CAUSE

This is caused by a problem in the compiler that overlooks proper initialization of these registers.

RESOLUTION

As a work-around, you may explicitly cast the dereferenced pointer to an XDATA pointer. For example, the following modified function:

unsigned char xdata DummyVariable;
unsigned char xdata Temp;

void TestFunction(void)
{
for(Temp=0;Temp<31;Temp++)
        {
                *((unsigned char xdata *) (&DummyVariable + (Temp * Offset))) = 0;
        }
}

generates correct code:

             ; FUNCTION TestFunction (BEGIN)
                                           ; SOURCE LINE # 22
                                           ; SOURCE LINE # 23
                                           ; SOURCE LINE # 24
0000 E4                CLR     A
0001 900000      R     MOV     DPTR,#Temp
0004 F0                MOVX    @DPTR,A
0005         ?C0001:
0005 900000      R     MOV     DPTR,#Temp
0008 E0                MOVX    A,@DPTR
0009 FF                MOV     R7,A
000A C3                CLR     C
000B 941F              SUBB    A,#01FH
000D 501A              JNC     ?C0004
                                           ; SOURCE LINE # 25
                                           ; SOURCE LINE # 26
000F EF                MOV     A,R7
0010 75F003            MOV     B,#03H
0013 A4                MUL     AB
0014 2400        R     ADD     A,#LOW DummyVariable
0016 F9                MOV     R1,A
0017 7400        R     MOV     A,#HIGH DummyVariable
0019 35F0              ADDC    A,B
001B 8982              MOV     DPL,R1
001D F583              MOV     DPH,A
001F E4                CLR     A
0020 F0                MOVX    @DPTR,A
                                           ; SOURCE LINE # 27
0021 900000      R     MOV     DPTR,#Temp
0024 E0                MOVX    A,@DPTR
0025 04                INC     A
0026 F0                MOVX    @DPTR,A
0027 80DC              SJMP    ?C0001
                                           ; SOURCE LINE # 28
0029         ?C0004:
0029 22                RET
             ; FUNCTION TestFunction (END)

STATUS

This problem is corrected in the C51 V6.21 release. You may download the latest updates from the Keil Website.

SEE ALSO

ATTACHED FILES

Request the files attached to this knowledgebase article.

Article last edited on: 2005-06-03 18:42:04

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential