February 22, 2006
C51中的函数指针
8051一个特别之处在于他不用stack而是用fixed memory locations给函数传参。因为8051的stack很小,只有128 bytes。
这样就造成了函数指针(function pointer)使用上的很多问题和限制。
上面说的fixed memory在链接时由编译器指定。
编译器根据程序代码生成一个Call Tree,就是函数调用的关系,谁调用了谁。
这样两个不同时调用的函数就可以共享同一块memory作为传参之用。
编译器不能聪明到知道函数指针代表的是哪一个函数。
初始化和把这个指针作为参数传递的时候,都有可能误认为是一次调用。
于是就会出现Call Tree的构造错误。
此时编译和链接都不会出错,直到运行时,就有可能两个同时运行的(比如funcA执行中调用funcB)函数的传参用地址重叠,发生错误。
可以用链接指令OVERLAY强制指定Call Tree的结构,来避免这个问题。
另外一个问题就是函数的非直接调用(indirectly called function)时,8051要把所有的参数都读到寄存器中。
但是寄存器的大小和个数有限,于是像函数指针这种非直接调用的函数,就最多只能使用三个参数,参数的大小也有限制。
可以考虑把参数放到一个结构(Struct)里面,然后传递这个结构的指针作为参数。
上面两个问题都可以通过reentrant机制来解决。
reentrant是8051提供的一种机制,在IDATA, PDATA, XDATA上面模拟一个Stack。
需要将函数和函数指针都声明成reentrant的。
reentrant会降低程序运行的效率。
C51中的函数指针问题,使得C++这样依靠函数指针实现虚函数等面向对象方法的编程语言无法使用。
Filed by
Charlie ZHU
at 1:41 am under Uncategorized
No Comments
2 Comments

