看看这个测试代码:
///////////////////main函数//////////////////// 5: void main(void) 6: { 7: code unsigned char x=3; //x为code区变量 8: test(&x); //调用test函数 C:0x0028 7BFF MOV R3,#0xFF ;R3为指针类型,这个是由keil编译时根据参数的类型自己加上的 C:0x002A 7A00 MOV R2,#0x00 ;这个是x这个变量的地址的高8位 C:0x002C 7938 MOV R1,#0x38 ;这个是x这个变量的地址的低8位 C:0x002E 120032 LCALL test(C:0032) ;调用函数test 9: } 10: C:0x0031 22 RET //main函数返回
//////////////test函数/////////////// 11: void test(unsigned char *p) 12: { 13: P0=*p; //这个函数只有一句: P0 = *p; C:0x0032 120003 LCALL C?CLDPTR(C:0003) ;编译器先调用库函数C?CLDPTR C:0x0035 F580 MOV P0(0x80),A ;C?CLDPTR函数返回的结果就在A中,再将A赋给P0,实际上,C?CLDPTR函数就根据指针类型选择了不同的类型 14: } C:0x0037 22 RET R3,#0xFE,C:0015 ;test函数返回
/////////C?CLDPTR函数////////// C?CLDPTR: C:0x0003 BB0106 CJNE R3,#0x01,C:000C ;根据指针类型(R3)跳转 ;如果R3的值为1,则表示xdata,将指针放放入DPTR C:0x0006 8982 MOV DPL(0x82),R1 C:0x0008 8A83 MOV DPH(0x83),R2 ;使用movx指令将DPTR指向的内容放入A并返回 C:0x000A E0 MOVX A,@DPTR C:0x000B 22 RET C:0x000C 5002 JNC C:0010 ;如果R3的值为0,则表示内部RAM的, C:0x000E E7 MOV A,@R1 ;根据指针低位用间接寻址将结果放入A C:0x000F 22 RET ;返回
C:0x0010 BBFE02 CJNE R3,#0xFE,C:0015 ;如果R3的值为0xFE,则表示pdata C:0x0013 E3 MOVX A,@R1 ;使用R1间接访问pdata C:0x0014 22 RET ;返回
;如果都不是以上情况,则说明是code的,应该使用movc指令访问 C:0x0015 8982 MOV DPL(0x82),R1 C:0x0017 8A83 MOV DPH(0x83),R2 C:0x0019 E4 CLR A C:0x001A 93 MOVC A,@A+DPTR C:0x001B 22 RET
最后那个clr A似乎有点多余,直接 MOVC A,@DPTR 不就得了,呵呵.这个编译器生成的,只能这样了。
|