c51语言 code 函数指针,keil c51函数指针.doc

keil c51函数指针

Keil C51 中的函数指针和再入函数,函数指针与overlay

=====

调用树的保存

?? C51不把函数参数压栈(除非使用再入函数)。函数参数和全局变量被存入寄存器或固定的存储空间。这样阻止函数的再入。例如,一个函数调用它自己,它将覆盖它自己的参数或存储空间。函数的再入问题通过关键字“reentrant”来解决。函数指针的非再入函数的副作用,在执行中出现问题。

MAIN函数调用FUNC和FUNC_CALLER(根据调用树)。

用函数的指针来传递参数,调用树往往会出错。

=====

转???????这篇文章是由Keil C51 的英文文档翻译过来的,很多语句都是根据自己的理解翻译的,肯定还有许多地方需要推敲。希望读者能吸取到有用的部分,不要被误解了,自己多理解。

Overlay修改用于数据覆盖的调用树。如果在用户程序里使用了函数指针,或者使用了像实时操作系统中调度器那样的跳转(k 指的是指针方式的调用吗?),那么,修改程序调用树将是很有必要的。

混合编程:

函数名?????????????????????? 符号名????????? 解释viod func(void)????????????? FUNC??????????? 无参数传递,或不含寄存器参数的函数名不作改变???????????????????????????????????????????? 转入目标文件中,名字只是简单地转为大写形式

viod func(char)????????????? _FUNC?????? 带寄存器参数的函数名加入“_”字符前缀,它表明???????????????????????????????????????? 这类函数包含寄存器内的参数传递

viod func(viod) reentrant??? _?FUNC????????? “_?”表示可重入,它表明该行数包含栈内的参数传递。

====

将下面这篇的难点内容提到前面

使用函数指针的附加说明

?? 如果你在C51中使用函数指针编程,有几个附加的说明你必须注意。

参数列表的限制

?? 通过函数指针传递参数给函数必须把所有的参数存入寄存器。在大部分情况下,3个参数能够自动通过寄存器传递。在C51的用户手册中能找到传递参数进入寄存器的运算法则。但是并不保证,任何的3个数据类型可以传递。

? 因为C51在寄存器中传递3个参数,用于传递参数的存储空间是不被分配的,除非函数指向一个要求更多参数的函数。如果在那样的情况下,可以把参数混入一个结构体中,然后通过一个结构体指针传递参数。如果这样不可接受,你可以使用再入函数(看下面)。

?

调用树的保存

?? C51不把函数参数压栈(除非使用再入函数)。函数参数和全局变量被存入寄存器或固定的存储空间。这样阻止函数的再入。例如,一个函数调用它自己,它将覆盖它自己的参数或存储空间。函数的再入问题通过关键字“reentrant”来解决。函数指针的非再入函数的副作用,在执行中出现问题。

?? 为了保护尽量多的数据空间,连接器执行调用树的性能分析,决定一些存储空间被安全的覆盖。例如,如果你的应用中包含main 函数,函数a,函数b,函数c,并且main函数调用a,b,c,但是a,b,c之间没有互相调用。在你应用中的调用树见出现如下:

MAIN

??? +→ A

??? +→ B

??? +→ C

这样A,B,C的存储空间可以被安全的覆盖。

?

当调用树不能正确的建立,函数指针将带来问题。因为连接器不能决定函数之间的引用。在这个问题上,没有自动的解决方法。

?

下面两个源文件将解答这个问题,使问题容易明白。第一个源文件FPCALLER.C,包括一个函数,它通过一个函数指针(fptr)调用另一个函数。

?

FPCALLER.C????? // 第一个源文件FPCALLER.C? (文件名)

?void ?func_caller(long (code *fptr) (unsigned int))?????// (函数名)

{

????? ? unsigned char i;

???? ? for(i=0;i<10;i++)

?????? ?{

????????(*ftpr)(i);

??????? }

}

?

第二个源文件FPMAIN.C,包含C主函数和被func_caller调用的函数func。?????? 注意main函数调用func_caller,把func的地址作为参数传递给func_caller。

?

FPMAIN.C????? // 第二个源文件FPMAIN.C (文件名)

extern ?void func_caller (long (code *) (unsigned int));

int ?func (unsigned i

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值