#pragma src
#include
f(){}
f1(){}
f2(){}
main()
{
{
int x;
int *px;
//下面这些表示虽然很烦,但是生成的代码却及其简洁:
//将 xdata 型指针 0x4000 赋给 px
px=(int xdata *)0x4000;
//表示从 xdata 0x4000处取一个 char 给x
x=*((char xdata *)0x4000);
// 表示从 code 0x4000处取一个 word 作为 xdata 型的指针 给
px
px=*((int xdata * xdata *)0x4000);
//表示从 code 0x4000处取一个 word 作为 xdata 型的指针,
//再把这个指针指向的char数据赋给x
x=**((char xdata * code *)0x4000);
//表示把函数f()入口地址当作xdata型指针,再把指向的xdata
//中的int型数据作为code型指针,把指向的code字节
//赋给x(晕,这样有意义吗?)
x=**(int code * xdata *)f;
//把f()入口地址处的ROM中两个code型字节,
//赋给堆栈指针SP指向的字节(想干什么?编操作系统?)
*(unsigned int idata *)SP=*(unsigned int code *)&f;
//表示把f()入口地址处的ROM中两个code型字节,
//作为一个xdata指针寻址,
//把指向的数据作为pdata指针寻址,
//再把把指向的数据作为idata指针寻址,
//把该地址处的一个字节赋给x (我靠,累死了)
x= ****(unsigned int data * idata * pdata * xdata * code
*)&f;
//总之,一个括号里面外面的"*"一样多就表示指向的是数据。
}
{
//数组函数
code void (*ArrFn[])(void) =
{ &f1,
&f2,
};
//可以像引用数组一样调用函数啦:
(*ArrFn[0])();
(*ArrFn[1])();
}
{
//这样将使函数调用0000H处:
void (*reset) (void);
reset=0x0;
(*reset)();
reset();
//或者直接这样,仅仅生成一条指令LCALL 1234H
((void (code *)(void))0x1234)();
}
{
//这样可以调用RETI指令:
#define INT_NUM 30 //空闲中断号
((void (code *)(void))(INT_NUM*8 3))();
//当然需要在外面声明 int_rpt()interrupt INT_NUM {}
}
{
//这样调用RETI指令太变态:
code unsigned char ret_i=0x32;
((void (code *)(void))(&ret_i))();
}
}
int_rpt()interrupt INT_NUM {}
相关文章