打印

C51 reentrant

[复制链接]
6402|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lenglx|  楼主 | 2007-7-23 21:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    近一段时间,发生了很多事情.差点郁闷死.
    好在事情终于,是的,"终于"过去了.
    呵呵,晚上一定要喝一杯的,不过我那般"狐朋狗友"还在"码砖",不到半夜,估计收不了场.
    
    哦,差点忘了,恭喜"救火车"竞选版主成功.
    前一段时间,心情不甚好,也没怎么关注这次"选举",这么大的事情,都没参与过,罪过罪过.
    
    以下是信手涂鸦的一点东西,希望能抛砖引玉,能有高人出来,指点一二.
    
    
    ===================================================================================
    
    如果你想要在C51中使用OS,那么同所有其它要使用OS的C语言一样,函数的重入线程的安全问题,都是需要特别注意的问题.
    C51更有它特别的地方.
    
    在其它环境下(比如PC,比如ARM),函数重入的问题一般不是要特别注意的问题.只要你没有使用static变量,或者指向static变量的指针,一般情况下,函数自然而然地就是可重入的.
    但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 用来解决函数重入的问题.
    
    
    至于线程安全的问题,跟其它环境下的C程序所要注意的问题,小心对待全局变量以及其它的共享资源,应当就能避免大多数的安全问题.
    
    不要以为你不使用OS,就不会碰到这些问题.
    实际上,如果你的程序有中断处理例程,那么中断例程和你的主程序在某种意义上,就是两个不同的线程.
    它们同OS的线程一样,在从一个例程到另一个例程的切换过程中,都需要保存现场环境,在退出时,恢复环境.
    
====================================================================================
另外,近来学习ARM,深感比51的好处多多,尤其是有C++可用.
不过年纪渐长,学习能力大不如前,希望找人提点提点. :-)        

相关帖子

沙发
ayb_ice| | 2007-7-24 08:03 | 只看该作者

地球人都知道...

使用特权

评论回复
板凳
hexenzhou| | 2007-7-24 11:28 | 只看该作者

多谢了,

学习了,

使用特权

评论回复
地板
gyt| | 2007-7-24 11:37 | 只看该作者

辛苦辛苦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

186

帖子

1

粉丝