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

Is it a compiler bug??

unsigned int Begin;
 ...
Begin=*(U16 CODE *)Begin;

 ...
;---- Variable 'Begin' assigned to Register 'DPTR' ----
002C 8F82              MOV     DPL,R7
002E F583              MOV     DPH,A
                                           ; SOURCE LINE # 82
0030 E4                CLR     A
0031 93                MOVC    A,@A+DPTR
0032 F583              MOV     DPH,A	 <--- Error: This line change the DPTR value.
0034 7401              MOV     A,#01H
0036 93                MOVC    A,@A+DPTR <--- Error: Wrong address.
0037 F582              MOV     DPL,A

  • You're casting an unititialised integer to a pointer then dereferencing it. The compiler is under no obligation to produce code that does anything useful or sensible in that type of situation.

    Stefan

  • Which C51-Compiler version do you use ?
    I think, the code is not correct, but I am not sure !

    Mike

  • C51 V7.01
    Here are my source codes (Compile O.K.)...

    void CopyRomData (U8 xdata *Des,U8 Index)
    {
        U8 code *pbSrc;
        unsigned int Begin;
        SysSetRomPage(ROM_PAGE1);
        Begin=(unsigned int)&((BankH1 CODE *)0)->OffsetData[Index];
        Begin=*(U16 CODE *)Begin;
        pbSrc=(U8 CODE *)Begin;
        do {
            *Des=*pbSrc;
            ++pbSrc;
            ++Des;
        } while(*pbSrc);
        *Des=0;
        SysSetRomPage(ROM_PAGE0);
        //Index=(U8)Begin;//Unmask this line will solve the error.
    }
    
    

    Assembler...
                 ; FUNCTION _CopyRomData (BEGIN)
                                               ; SOURCE LINE # 152
    0000 8E00        R     MOV     Des,R6
    0002 8F00        R     MOV     Des+01H,R7
    0004 8D00        R     MOV     Index,R5
                                               ; SOURCE LINE # 153
                                               ; SOURCE LINE # 156
    0006 7F10              MOV     R7,#010H
    0008 120000      E     LCALL   _SysSetRomPage
                                               ; SOURCE LINE # 157
    000B E500        R     MOV     A,Index
    000D 75F002            MOV     B,#02H
    0010 A4                MUL     AB
    0011 2438              ADD     A,#038H
    0013 FF                MOV     R7,A
    0014 E4                CLR     A
    0015 35F0              ADDC    A,B
    ;---- Variable 'Begin' assigned to Register 'DPTR' ----
    0017 8F82              MOV     DPL,R7
    0019 F583              MOV     DPH,A
                                               ; SOURCE LINE # 159
    001B E4                CLR     A
    001C 93                MOVC    A,@A+DPTR
    001D F583              MOV     DPH,A  'pbSrc' assigned to Register 'R6/R7' ----
    0027         ?C0035:
                                               ; SOURCE LINE # 163
                                               ; SOURCE LINE # 164
    0027 8F82              MOV     DPL,R7
    0029 8E83              MOV     DPH,R6
    002B E4                CLR     A
    002C 93                MOVC    A,@A+DPTR
    002D 850082      R     MOV     DPL,Des+01H
    0030 850083      R     MOV     DPH,Des
    0033 F0                MOVX    @DPTR,A
                                               ; SOURCE LINE # 165
    0034 0F                INC     R7
    0035 BF0001            CJNE    R7,#00H,?C0053
    0038 0E                INC     R6
    0039         ?C0053:
                                               ; SOURCE LINE # 166
    0039 0500        R     INC     Des+01H
    003B E500        R     MOV     A,Des+01H
    003D 7002              JNZ     ?C0054
    003F 0500        R     INC     Des
    0041         ?C0054:
                                               ; SOURCE LINE # 167
    0041 8F82              MOV     DPL,R7
    0043 8E83              MOV     DPH,R6
    0045 E4                CLR     A
    0046 93                MOVC    A,@A+DPTR
    0047 70DE              JNZ     ?C0035
                                               ; SOURCE LINE # 168
    0049 850082      R     MOV     DPL,Des+01H
    004C 850083      R     MOV     DPH,Des
    004F F0                MOVX    @DPTR,A
                                               ; SOURCE LINE # 169
    0050 FF                MOV     R7,A
    0051 020000      E     LJMP    _SysSetRomPage
                 ; FUNCTION _CopyRomData (END)
    
    

  • Looks like a code generator bug to me. "Begin" lives in the DPTR; it takes two MOVCs to fetch a new value; and the first MOVC goes (almost) straight into the DPTR, altering it before the MOVC of the second byte. The address used for the second MOVC is not the same as the address used for the first MOVC.

    It may be that the optimizer thinks it's okay to trash the value of Begin because it will no longer be used. That would explain why uncommented the later statement fixes the problem. The compiler would preserve the value of Begin for the later use.

    You don't need to assign Begin back to itself anyway; it's just a temporary. How about just:

    pbSrc = (U8 CODE *)
        *(U16 CODE *)(&((BankH1 CODE *)0)->OffsetData[Index]);
    

    You could probably clean up the code a lot with the proper declarations to avoid all that intermediate casting. We can't see the declaration for BankH1, but the offset of OffsetData could be folded into the hard-wired address 0, and then you could just add index to the base (or use the array reference syntax). Or perhaps just declare a BankH1 _at_ 0.

  • perhaps it would help if you could just state in words what you're actually trying to do?

  • What are the U8 and U16 types?

    Also, why not try this with the latest C51 release? There have been 9 releases since 7.01.

    Jon

  • Thanks a lot for all your kindly reply!

    I know my code looks weird, such as

    Begin=*(U16 CODE *)Begin;//U16 means unsigned short
    
    In fact, I do it this way for purpose. I run my program on both Target(Real 8051 ICE) and PC(Windows Simulator). See the complete code below...
    void CopyRomData (U8 XDATA *Des,U8 Index)
    {
        U8 CODE *pbSrc;
        unsigned int Begin;//Keil 2B, Win32 4B.
        SysSetRomPage(ROM_PAGE1);//Change Bank, it means the following "MOVC" will retrieve data from specify bank.
        Begin=(unsigned int)&((BankH1 CODE *)0)->OffsetData[Index];//Data offsets are located on begginning of each bank.
        WinWork(winGetRomAddr(&Begin));//For simulator.
        Begin=*(U16 CODE *)Begin;
        WinWork(Begin=U16X(Begin));//Hi-Lo exchange, little-Endian for PC.
        WinWork(winGetRomAddr(&Begin));//For simulator.
        pbSrc=(U8 CODE *)Begin;//Both Target and PC could get the right address.
        strcpy(Des,pbSrc);//I just want to copy string, but keil's library seems refer to 'MOVC' internal(It will access to wrong bank), That's why I wrote a loop myself(see pre post).
        SysSetRomPage(ROM_PAGE0);
    }
    
    

    My target contains 4 banks. I put all my programs on bank#0(prevent bank switch and common area issue), and the others are const data, such as Fonts,Bitmaps,Midi,String(In this case), etc.
    Of course, I have my own tools for creating those bank's images, and , my little simulator could help me to check if there are O.K. or not. When I found the program is O.K. on PC, but error on Target. Then I starting to solve the problem, until I found the compiler's issue that I metion before.

    My CA51-v7.0 product is out of date (1 year/Bought on Sep2002). Can I still download the most update version?

  • My CA51-v7.0 product is out of date (1 year/Bought on Sep2002). Can I still download the most update version?

    You should be able to download 7.07 or 7.07a.

    Jon