打印
[51单片机]

**仔单片机成长记----------------浅谈51堆栈操作

[复制链接]
960|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liuyusheng86|  楼主 | 2016-9-8 20:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天来谈一下51的堆栈操作,堆栈是什么?堆栈是单片机在片内数据存储器中用与存储临时数据的区域,以SP来确定位置,8位寄存器,复位的时候值位07H。可以用MOV SP,#data来改变值。
        用GCC来编译C语言中堆栈的操作与用KEIL中C程序对堆栈的操作不一样,下面先来说一下GCC编译中堆栈的操作:
--------------------------------------- GCC中函数调用过程----------------------------------------------
        1>保存断点地址,即PC的值入栈,并且将PC的值赋值为要执行函数的地址,实际上是用LCALL实现的。
        2>实际参数入栈。
        3>为被调用函数分配存储空间。
        4>被调函数从栈中取得参数,并开始执行函数体。(通过计算SP的值来计算出参数的地址)
        5>被调函数执行结束前(return前),先将返回值入栈,函数执行结束,空间收回。
        6>主调函数从栈中获得返回值。
        7>主调函数从栈中获得断点地址。并从断点处继续运行(在这里读一下SP的值,栈空间的大小也就能估算了)
        注意:每种编译器的处理方式都有些许差别,但是总的流程大体一致。
        有些CPU的编译器在参数少的时候且参数类型简单时,会用CPU的寄存器来传递参数,
但碰到参数比较多或者类型复杂的状况时,一定是用stack来传参数。
----------------------------------------Cx51编译器中函数调用--------------------------------------------
        1>Cx51为每个参数分配一个特殊的地址
        2>函数被调用时,调用者在传递控制权之前必须拷贝参数到分配好的存储区,函数就可以
在从固定的存储区提取参数,在这个过程中,只有返回地址保存在堆栈中,中断函数要更多的空间,因为要保存一些
寄存器的值
        3>函数调用之后,出栈PC。调用者继续运行。
        注意:在缺省条件下,Cx51最多可以用寄存器传递3个参数,若无寄存器可用,则用固定地址存放。
CPU寄存器经常用来返回函数的返回值。把局部变量分配到固定的内存位置或者寄存器中,而不是堆栈中。
还可能把不同函数的局部变量分到同一位置,这些都是以节约RAM为目的的。
------------------------------------------------实例分析-------------------------------------------------------
#include <reg52.h>void delay(bit b,unsigned char a)
//void delay(unsigned char a,bit b)
{        
}
void main()
{        
        while(1)        
        {               
                   delay(1,50);
//                delay(50,1);               
         }
}
将上面的程序在KEIL中调试,并观察汇编代码,如下图:

        这里的函数先传递参数是位类型的,放在位可寻址区里,第二个参数放在了固定地址里。也没有
用寄存器传递参数啊!!!!!!这是什么鬼,让我们在看一张图:

        这里我们可以清晰的看到了,第一个参数放在R7中了,而第二个还是在位可寻址区里面。
        别着急,让我们在看一张图:

        别急,在来一张:

        聪明的人从图中就能看出端倪来了,让我来依次说明下:
        1>从第一和第二张图我们可以看到,如果有参数是bit型的,则传递的时候最好是放在最后面,
因为如果第一个参数是bit型的,Cx51就不会把剩下的参数用寄存器去传递,而是放在RAM的特定地址中。
        2>Cx51最多只能用3个寄存器来传递参数,如果参数个数大于3个,剩下的就只能放在RAM的特定地址中了。
        接下来看一下中断的处理:


        从图上可以看出来:在进入中断有PUSH操作,在退出中断的时候有POP操作,这就是所谓的保护现场,而且SP的值也变了,这就是入栈和出栈的过程了。从图中我们还可以看到,堆栈是从高地址向低地址生长的。
        今天就到这里了。我这里有关于KEIL的编译文档,现在不在身边,等有时间我传上来吧。

相关帖子

沙发
xxdcq| | 2016-9-11 10:57 | 只看该作者
用C做是看不到堆栈的具体操作的,只有汇编才可以看到这个过程

使用特权

评论回复
板凳
冰零分子| | 2016-9-11 13:20 | 只看该作者
感谢分享

使用特权

评论回复
地板
JamLin| | 2016-10-26 17:08 | 只看该作者
感谢分享~

使用特权

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

本版积分规则

4

主题

21

帖子

0

粉丝