keilc51可重入函数及模拟栈浅析
ic变量的指针,一般情况下,函数自然而然地就是可重入的. 但C51不一样,如果你不特别设计你的函数,它就是不可重入的. 引起这个差别的原因在于:一般的C编译器(或者更确切点地说:基于一般的处理器上的C编译器),其函数的局部变量是存放于堆栈中的,而C51是存放于一个可覆盖的(数据)段中的. 至于C51这样做的原因,不是象有些人说的那样,为了节约内存.事实上,这样做根本节约不了内存.理由如下: 1) 如果一个函数func1调用另一个函数func2,那么func1,func2的局部变量根本就不能是同一块内存.C51还是要为他们分配不同的RAM.这跟使用堆栈相比,节约不了内存. 2) 如果func1,func2不是在一个调用链上,那么C51可以通过覆盖分析,让它们的局部变量共享相同的内存地址.但这样也不会比使用堆栈节约内存.因为既然它们是在不同的调用链上,那么当其中一个函数运行时,那么另外一个函数必然不在其生命期内,它所占用的堆栈也已释放,归还给系统. 真实的原因(C51使用覆盖段作为局部变量的存放地的原因)是: 51的指令系统没有一个有效的相对寻址(变址寻址)的指令,这使得使用堆栈作为变量的代价太过昂贵. 使用堆栈存放变量的一般做法是: 进入函数时,保留一段堆栈空间,作为变量的存放空间,用一个可作为基址寻址的寄存器指向这个空间,通过加上一个偏移量,就可以访问不同的变量了. 例如: MOV EAX, [EBP + 14];X86指令 LDR R0, [R12, #14];ARM指令 都可以很好的解决这个问题. 但51缺少这样的指令. *其实,51中还是有2个可变址寻址的指令的,但不适合访问堆栈的局部变量这样的场合. MOVC A, @A+DPTR MOVC A, @A+PC 所以,C51有个特别的关键字: reentrant 用来解决函数重入的问题.
- 总线技术的应用浅析(12-16)
- 嵌入式操作系统浅析(09-12)
- 关于Linux 内核配置系统浅析(08-29)
- 浅析μC/OS-ⅡAPI的设计思想及实现机制(08-24)
- 浅析μC/OS-Ⅱ设备驱动的设计与实现(08-24)
- 浅析TMS320F2812片内Flash在线烧写技术(07-18)