可重入函数和模拟堆栈

可重入函数和模拟堆栈

ID:8829474

大小:77.00 KB

页数:8页

时间:2018-04-08

可重入函数和模拟堆栈_第1页
可重入函数和模拟堆栈_第2页
可重入函数和模拟堆栈_第3页
可重入函数和模拟堆栈_第4页
可重入函数和模拟堆栈_第5页
资源描述:

《可重入函数和模拟堆栈》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、作者:xzp21st  邮箱:tyter1223@163.com撰文辛苦,转载请注明作者及出处关键字:keilc51,模拟堆栈,可重入函数调用,参数传递,C?XBP,C?ADDXBP摘要:本文较详细的介绍了keilc51可再入函数和模拟堆栈的一些概念和实现原理,通过一个简单的程序来剖析keilc51在大存储模式下可重入函数的调用过程,希望能为keilc51和在51系列单片机上移植嵌入式实时操作系统的初学者提供一些帮助。1、关于可重入函数(可再入函数)和模拟堆栈(仿真堆栈)“可重入函数可以被一个以上的任务调用,而不必担心数据被破坏。可重入函数任何时候都可以被中断,一段时间以后又可

2、以运行,而相应的数据不会丢失。”(摘自嵌入式实时操作系统uC/OS-II)在理解上述概念之前,必须先说一下keilc51的“覆盖技术”。(采用该技术的原因请看附录中一网友的解释)(1)局部变量存储在全局RAM空间(不考虑扩展外部存储器的情况);(2)在编译链接时,即已经完成局部变量的定位;(3)如果各函数之间没有直接或间接的调用关系,则其局部变量空间便可覆盖。正是由于以上的原因,在KeilC51环境下,纯粹的函数如果不加处理(如增加一个模拟栈),是无法重入的。举个例子:voidTaskA(void*pd){inta;//其他一些变量定义do{//实际的用户任务处理代码}whil

3、e(1);}voidTaskB(void*pd){intb;//其他一些变量定义do{func();//其他实际的用户任务处理代码}while(1);}voidfunc(){intc;//其他变量的定义//函数的处理代码}在上面的代码中,TaskA与TaskB并不存在直接或间接的调用关系,因而它们的局部变量a与b便是可以被互相覆盖的,即它们可能都被定位于某一个相同的RAM空间。这样,当TaskA运行一段时间,改变了a后,TaskB取得CPU控制权并运行时,便可能会改变b。由于a和b指向相同的RAM空间,导致TaskA重新取得CPU控制权时,a的值已经改变,从而导致程序运行不正确

4、,反过来亦然。另一方面,func()与TaskB有直接的调用关系,因而其局部变量b与c不会被互相覆盖,但也不能保证func的局部变量c不会与TaskA或其他任务的局部变量形成可覆盖关系。根据上述分析我们很容易就能够判断出TaskA和TaskB这两个函数是不可重入的(当然,func也不可重入)。那么如何让函数成为可重入函数呢?C51编译器采用了一个扩展关键字reentrant作为定义函数时的选项,需要将一个函数定义为可重入函数时,只要在函数后面加上关键字reentrant即可。与非可重入函数的参数传递和局部变量的存储分配方法不同,C51编译器为可重入函数生成一个模拟栈(相对于系统

5、堆栈或是硬件堆栈来说),通过这个模拟栈来完成参数传递和存放局部变量。模拟栈以全局变量?C_IBP、?C_PBP和?C_XBP作为栈指针(系统堆栈栈顶指针为SP),这些变量定义在DATA地址空间,并且可在文件startup.a51中进行初始化。根据编译时采用的存储器模式,模拟栈区可位于内部(IDATA)或外部(PDATA或XDATA)存储器中。如表1所示:存储模式栈指针栈区域Small?C_IBP(1字节)间接访问的内部数据存储器(IDATA),栈区最大为256字节Compact?C_PBP(1字节)分页寻址的外部数据存储器(PDATA),栈区最大为256字节Large?C_XB

6、P(2字节)外部数据存储器(XDATA),栈区最大为64K表1注意:51系列单片机的系统堆栈(也叫硬件堆栈或常规栈)总是位于内部数据存储器中(SP为8位寄存器,只能指向内部),而且是“向上生长”型的(从低地址向高地址),而模拟栈是“向下生长”型的。1、可重入函数参数传递过程剖析在进入剖析之前,先简单讲讲c51函数调用时参数是如何传递的。简单来说,参数主要是通过寄存器R1~R7来传递的,如果在调用时,参数无寄存器可用或是采用了编译控制指令“NOREGPARMS”,则参数的传递将发生在固定的存储器区域,该存储器区域称为参数传递段,其地址空间取决于编译时所选择的存储器模式。利用51单

7、片机的工作寄存器最多传递3个参数,如表2所示。传递的参数char、1字节指针int、2字节指针long、float一般指针第一个参数R7R6,R7R4~R7R1,R2,R3第二个参数R5R4,R5R4~R7R1,R2,R3第三个参数R3R2,R3无R1,R2,R3表二举两个例子:func1(inta):“a”是第一个参数,在R6,R7中传递;func2(intb,intc,int*d):“b”在R6,R7中传递,“c”在R4,R5中传递,“*d”则在R1,R2,R3中传递。至于函数的返回值通

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。