We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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. }
; 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]);
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
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 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
Jon, Thank you! Kenny