Keil C51对C语言的关键词扩展之十五: reentrant

原创 2013年12月02日 20:56:06

reentrant声明的函数为可重入函数。可重入的函数能够被多个进程同时调用。可重入函数在执行时,另外的进程可以中断当前执行的函数,并且调用同一个函数。正常情况下,C51程序中的函数不能被递归地调用,这是由于函数的参数和局部变量都被保存在固定的地址,在递归调用时操作了相同存储位置,导致数据被覆盖。

使用reentrant声明函数为可递归调用的可重入函数:

int calc (char i, int b) reentrant  {
  int  x;
  x = table [i];
  return (x * b);
}
可重入函数,能够被递归调用,也能被两个以上的进程同时调用。可重入函数通常在实时应用或者中断与非中断程序共享相同函数这两种情况下被使用。

每个可重入函数都有一个位于内部ram或外部ram的模拟堆栈:

1)SMALL内存模型下,可重入函数模拟堆栈位于idata区;

2)COMPACT内存模型下,可重入函数模拟堆栈位于pdata区;

3)LARGE内存模型下,可重入函数模拟堆栈位于xdata区;

使用reentrant声明可重入函数须遵循的规则:

1)可重入函数不支持位寻址变量,比如bit类型的参数;

2)可重入函数不能被alien函数调用;

3)可重入函数不能被声明为alien属性(alien用于使能PL/M-51参数传递约定);

4)可重入函数可以同时拥有其他属性,比如using、interrupt、small、compact、large;

5)返回地址被保存在硬件堆栈中;

6)使用不同存储模型的可重入函数能够混合,但是各自函数声明时必须指定存储模型;

7)三种内存模型的可重入函数都有自己的对战区和栈指针。比如在相同模块中,定义了small和large类型的可重入函数,则small和large类型的堆栈及其堆栈指针都被创建;

可重入堆栈模拟体系,效率比较低下,但是由于8051自身缺乏适当寻址方法的硬件特性,所以推出这种堆栈模拟体系来满足我们的可重入需求,在应用中 ,我们应该尽量不用或少用可冲入函数。

可重入函数使用的模拟堆栈拥有独立于8051硬件堆栈的栈指针。堆栈和堆栈指针在STARTUP.A51文件中被定义和初始化。

下表列出了三种内存模型下的模拟堆栈指针名称、大小、数据区域:

内存模型        指针   堆栈信息
SMALL ?C_IBP        
(1 字节) 
    堆栈位于间接寻址的内部ram(idata). 最大可重入堆栈容量256字节. 访问该模拟堆栈,须要使用 R0 或 R1装载?C_IBP 的值,然后使用       MOV A, @R0/@R1 或 MOV @R0/@R1, A 指令。
COMPACT      ?C_PBP
(1 字节)
    堆栈位于可页寻址的外部ram。 最大容量256 字节。 访问该模拟堆栈,须要使用 R0 或 R1装载?C_PBP 的值,然后使用MOVX A, @R0/@R1 或 MOVX @R0/@R1, A 指令。
LARGE ?C_XBP
(2 字节)
    堆栈位于外部ram。 T最大堆栈容量64KB。 访问该模拟堆栈,须要使用DPTR 装载?C_XBP 的值,然后使用MOVX A, @DPTR 或 MOVX @DPTR, A 指令。
8051硬件堆栈向上增长,堆栈指针先加再压栈,可重入模拟堆栈正好相反,其指针先减再压栈。

STARTUP.A51启动代码声明并初始化了模拟堆栈及其堆栈指针,如果使用可重入函数就必须修改启动代码指出哪个模拟堆栈须要初始化。可以在启动代码中修改模拟堆栈的起始地址。

可重入函数的参数传递,通过模拟堆栈的压栈、出栈完成。

可重入函数的局部变量,也保存在模拟堆栈中,通过模拟堆栈指针访问。





版权声明:本文为博主原创文章,未经博主允许不得转载。

c51 reentrant 关键字,用法的一点理解,欢迎板砖!

/* 单片机分 端口映射 和 内存映射 51 为端口映射 但亦可以扩展为内存映射 那样就是混合映射 大部分的非51 cpu为内存映射 端口映射的CPU需要对c语言进行扩展,扩展端口映射语句,s...
  • helezh
  • helezh
  • 2014年09月12日 09:44
  • 1475

C51中的reentrant

C51中的reentrant 关于reentrant的使用keil的官方论坛上有详细的讨论. Andy Neil(官方工程师)建议 "Are you sure that ...

C51的再入函数 reentrant RECURSIVE CALL TO SEGMENT

重入函数,又叫再入函数,是一种可以在函数体内不直接或间接调用其自身的一种函 数。 再入函数可被递归调用,无论何时,包括中断函数在内的任何函数都可以调入。再入 函数在 C51编译时使用的是模拟栈...

Keil C51对C语言的关键词扩展之十五: reentrant

reentrant声明的函数为可重入函数。可重入的函数能够被多个进程同时调用。可重入函数在执行时,另外的进程可以中断当前执行的函数,并且调用同一个函数。正常情况下,C51程序中的函数不能被递归地调用,...

Keil C51对C语言的关键词扩展之十四: interrupt

8051/8052系列单片机标准向量表: 中断号       描述    地址              0 外部中断0  0003h 1 定时/计...

Keil C51对C语言的关键词扩展之十八:using

在8051系列单片机中,内部ram的前32个字节被分为4组,每组8个寄存器。每组的8个寄存器名字都为R0-R7。通过设置PSW寄存器的两个位,可以选择使用4组寄存器中的哪一组。 寄存器组在处理中断或...

C语言关键词C/C++ Keywords

cppreference.com -> C/C++ Keywords C/C++ Keywords asm 插入一个汇编指令. auto 声明一个本地变量. ...

KEIL C51环境下,汇编与C语言交叉编译的问题

1. 关于如何在C语言中嵌入汇编命令: 转载自:http://www.keil.com/support/docs/2308.htm C51: GETTING INLINE ASSEMBLY T...

C51对C的扩展专题

  • 2011年12月23日 09:11
  • 2.08MB
  • 下载

C语言精确延时 51单片机 Keil C

  • 2009年12月02日 13:16
  • 934B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Keil C51对C语言的关键词扩展之十五: reentrant
举报原因:
原因补充:

(最多只允许输入30个字)