Hi all,
In my project, I write some codes like this sample:
1 void foo(char xdata *pbuf, char a, char b) 2 { 3 int pdata bufaddr; 4 long pdata testval; 5 6 testval = 0x200; 7 bufaddr = pbuf; 8 } 9 10 void main(void) 11 { 12 char xdata buf[10]; 14 15 foo(buf, 0, 1); 16 }
And C51 would be compile these codes to this assembly:
; FUNCTION _foo (BEGIN) ; SOURCE LINE # 1 0000 8D00 R MOV a,R5 0002 8B00 R MOV b,R3 ;---- Variable 'pbuf' assigned to Register 'DPTR' ---- 0004 8F82 MOV DPL,R7 0006 8E83 MOV DPH,R6 ; SOURCE LINE # 2 ; SOURCE LINE # 6 0008 7800 R MOV R0,#LOW testval 000A 120000 E LCALL ?C?LSTKPDATA 000D 00 DB 00H 000E 00 DB 00H 000F 02 DB 02H 0010 00 DB 00H ; SOURCE LINE # 7 0011 AF82 MOV R7,DPL 0013 7800 R MOV R0,#LOW bufaddr 0015 E583 MOV A,DPH 0017 F2 MOVX @R0,A 0018 08 INC R0 0019 EF MOV A,R7 001A F2 MOVX @R0,A ; SOURCE LINE # 8 001B 22 RET ; FUNCTION _foo (END) ; FUNCTION main (BEGIN) ; SOURCE LINE # 10 ; SOURCE LINE # 11 ; SOURCE LINE # 14 0000 7E00 R MOV R6,#HIGH buf 0002 7F00 R MOV R7,#LOW buf 0004 7B01 MOV R3,#01H 0006 E4 CLR A 0007 FD MOV R5,A 0008 020000 R LJMP _foo ; FUNCTION main (END)
C51 would assign parameter pbuf to DPTR when function foo is called. Then in foo function, program first would call ?C?LSTKPDATA to assign a constant long type value to testval. ?C?LSTKPDATA would do the following assembly:
D083 POP DPH(0x83) D082 POP DPL(0x82) E4 CLR A 93 MOVC A,@A+DPTR F2 MOVX @R0,A 08 INC R0 7401 MOV A,#0x01 93 MOVC A,@A+DPTR F2 MOVX @R0,A 08 INC R0 7402 MOV A,#0x02 93 MOVC A,@A+DPTR F2 MOVX @R0,A 08 INC R0 7403 MOV A,#0x03 93 MOVC A,@A+DPTR F2 MOVX @R0,A 7404 MOV A,#0x04 73 JMP @A+DPTR
When finished ?C?LSTKPDATA, program would assign pbuf value to bufaddr. But pbuf is stored in DPTR, and ?C?LSTKPDATA used DPTR to assgin value before, it cause pbuf value in DPTR is overwrited, so the bufaddr would store the wrong value.
It seems this situation is caused by optimization of C51. I want to ask whether any method to prevent this situation occur.
Thanks all.