黄鼠狼进屋是什么兆头| evisu是什么牌子中文| 6月21是什么星座| 福禄安康是什么意思| 上梁不正下梁歪是什么意思| 深圳属于什么方向| 白癜风是什么样子的| 什么人容易得间质瘤| 成龙真名叫什么名字| 老是放屁吃什么药| abo什么意思| 胃不好吃什么水果好| 乳清粉是什么东西| 碳水化合物对人体有什么作用| 跨宽穿什么裤子好看| 胃疼吃什么药好得最快最有效| 肚子疼吐了是什么原因| 打胎药叫什么| 胸为什么会下垂| 轻度肠上皮化生是什么意思| 4月份是什么季节| 瘰疬是什么病| 失重感是什么感觉| 2023年是什么生肖年| 北京户口有什么好处| 宝宝发烧拉肚子是什么原因| 什么是射频消融术| 渗透压是什么意思| 1905年是什么朝代| b型阳性血是什么意思| 一五行属什么| 辣椒炒肉用什么辣椒| 吉可以加什么偏旁| 查肾功能需要做什么检查| 转注是什么意思| 为什么一生气就胃疼| 金不换是什么菜| 神经纤维是什么| 量贩式ktv什么意思| 黑眼圈是什么原因造成的| 两仪是什么意思| 锁骨属于什么骨| 月亮为什么是红色的| 耳朵痒是什么原因引起的| 男士背心什么牌子好| 大枣枸杞泡水喝有什么好处| 肺气不足有什么症状| 自信过头叫什么| 煮毛豆放什么调料| 什么花代表永恒的爱| 酒糟是什么东西| 不丹为什么不和中国建交| 奶粉可以做什么美食| c反应蛋白高吃什么药| 隔离霜有什么作用| 胃肠湿热吃什么中成药| 小马是什么牌子| penis是什么意思| 尿检4个加号什么意思| 牙龈流血是什么原因| mv是什么意思| 脓是什么| 夏天流鼻血是什么原因| 吃什么降血压| 抖腿是什么原因| 载波是什么意思| 成人礼送什么礼物| 十月五号是什么星座| 牙齿发黄是什么原因导致的| 眼睛长麦粒肿用什么药| 去非洲要打什么疫苗| 毛的部首是什么| 孕晚期感冒可以吃什么药| 玫瑰和月季有什么区别| 三十六计第一计是什么计| 蓁字五行属什么| 非甾体是什么意思| 92年是什么年| ct挂号挂什么科| 气管炎吃什么药最有效| 喝酒眼睛红是什么原因| 什么是君子| mt什么意思| 手为什么会发麻| 桃花有什么颜色| 什么是包容| 清洁度三度什么意思| 肺纤维化是什么意思| 小孩下半夜咳嗽是什么原因| 网络诈骗打什么电话| 畸胎瘤是什么病严重吗| 夜间多梦是什么原因| 进是什么结构| 银河系的中心是什么| 肾火吃什么药| 肚子疼拉肚子吃什么药| 巡警是做什么的| 孔明属什么生肖| 到底为什么| 兵马俑是什么意思| 胆固醇偏高吃什么好| 亡羊补牢说明什么道理| 什么是单克隆抗体| hpv68阳性是什么意思| 养心吃什么食物好| 什么是普世价值| 步幅是什么意思| 彩色相片什么时候出现| bp是什么职位| m倾向是什么意思| 孩子肚子有虫子有什么症状| 高血压注意什么事项| 尿频吃什么药最快见效| 撕裂性骨折是什么意思| 西红柿什么时候吃最好| 虎毒不食子是什么意思| 溜冰是什么意思| 和包是什么| 全职是什么意思| 脸上长闭口是什么原因导致的| 态度是什么| 自汗吃什么中成药| 左是什么结构的字| 皮下脂肪瘤挂什么科| 果子狸是什么动物| 大保健什么意思| 什么是化学性肝损伤| 血脂高有什么症状表现| 入赘是什么意思| 没吃多少东西但肚子很胀是什么| 咽喉炎是什么原因引起的| 1943年属羊的是什么命| 北京大裤衩建筑叫什么| 敏感肌是什么意思| 吃石斛有什么好处| 阿联酋和迪拜什么关系| 洗牙后要注意什么| 庚子是什么时辰| 吃什么不会长胖| 烟酰胺是什么| 白佛言是什么意思| 胰岛素有什么副作用| 茭白是什么植物| 人流后吃什么恢复快| hp感染是什么病| 小腿酸什么原因| 加应子是什么水果| l1椎体在什么位置| 前壁后壁有什么区别| 代谢慢吃什么效果最快| 英语四级什么时候报名| 什么叫烟雾病| 什么云霄| 我国的国花是什么花| 什么是梨形身材| 抱窝是什么意思| 受益匪浅的意思是什么| 西南方向是什么方位| 右边肋骨疼是什么原因| 多囊卵巢综合症吃什么食物好| 内热是什么原因引起的怎么调理| 如果是什么意思| 检查盆腔炎做什么检查| 中统和军统有什么区别| 甲功三项能查出什么病| 慢性气管炎吃什么药最有效| 节节草有什么作用| 鼻窦炎是什么原因引起的呢| 孩子大便出血什么原因| 正常白带什么样| gin是什么意思| 女性多囊是什么意思| 还替身是什么意思| 舌头两侧溃疡吃什么药| 塞来昔布是什么药| 药剂师是什么专业| 双向转诊是什么意思| 维生素a是什么| 各位同仁用在什么场合| 胆囊病变是什么意思| lov是什么意思| 什么的老师| 马兰头是什么菜| 什么窃什么盗| 老生气会得什么病| 高密度脂蛋白低是什么原因| 落拓是什么意思| 为什么日语怎么说| 北京西单附近有什么好玩的| 梦见钓了好多鱼是什么意思| 更年期综合征吃什么药| 泰迪吃什么| 举案齐眉是什么意思| 甜蜜素是什么| 肠胃出血有什么症状| 外阴裂口用什么药| 擦伤用什么药好得快| 佰草集属于什么档次| 轻度脂肪肝吃什么药| 什么茶降血压效果最好| 手癣用什么药| vp是什么| 鸡珍是什么| 什么时候初伏第一天| 肠镜检查前需要做什么准备工作| 什么样的人长寿| 蛇舌草有什么功效| 痰湿阻滞吃什么中成药| 便溏什么意思| 胆红素是什么意思| 异常脑电图说明什么| 什么时候做四维| 吃小龙虾不能和什么一起吃| 什么是阳虚| 杏仁是什么| 高血压是什么原因引起的| 工薪阶层是什么意思| 心脏造影是什么检查| 地铁什么时候停运| 化疗期间吃什么| anca医学上是什么意思| 人体最长的骨头是什么| 胆囊切除后吃什么好| 射手座和什么座最配对| 刺史是什么官职| 大学校长什么级别| 什么叫上升星座| 腰痛去医院挂什么科| 小孩说话不清楚挂什么科| 什么花适合送老师| 考试前不能吃什么| 送什么礼品好| 脚热是什么原因引起的| 有福气是什么意思| 鱼子酱为什么那么贵| 什么动物会冬眠| 下午七点是什么时辰| 小便无力是什么原因| 膀胱在什么位置图片| 气血不足吃什么好| 四五天不排便是什么原因| 破溃是什么意思| 大腿肿胀是什么原因| 百里挑一是什么生肖| 左侧卵巢囊性结构什么意思| 雪貂吃什么| 鼻头长痘痘什么原因| 朱砂痣什么意思| 导管室是干什么的| 5月13号是什么星座| 阴道里面有个肉球是什么| 考虑是什么意思| 有主见是什么意思| 把头是什么意思| 贪吃的动物是什么生肖| 哺乳期感冒可以吃什么药| 吃什么能变白| 曹字五行属什么| 肾萎缩吃什么药好| 领域是什么意思| 天肖是什么生肖| 牙刷属于什么垃圾| 手指是什么生肖| 小手指麻木是什么原因引起的| 百度

新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Cx51程序设计堆栈的计算方法

作者: 时间:2025-08-04 来源:网络 收藏
百度 传动系统方面,与发动机匹配的是9速手自一体变速器。

引言

  用C语言进行MCS51系列单片机是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己的特点。本文介绍的是Cx51的计算方法。

  1的溢出问题

  MCS51系列单片机将设置在片内RAM中,由于片内RAM资源有限,堆栈区的范围也是有限的。堆栈区留得太大,会减少其他数据的存放空间,留得太少则很容易溢出。所谓堆栈溢出,是指在堆栈区已经满了的时候还要进行新的压栈操作,这时只好将压栈的内容存放到非堆栈区的特殊功能寄存器(SFR)中或者堆栈外的数据区中。特殊功能寄存器的内容影响系统的状态,数据区的内容又很容易被程序修改,这样一来,之后进行出栈操作(如子程序返回)时内容已变样,程序也就乱套了。因此,堆栈区必须留够,宁可大一些。要在设计中防止堆栈的溢出,要解决两个问题:第一,精确计算系统分配给用户的堆栈大小,假设是M;第二,精确计算用户需要堆栈的大小,假设是N。要求M≥N,下面分别分析这两个问题。

  2计算系统

  分配给用户的堆栈大小设计中,因为动态局部变量是长驻内存中的,实际上相当于局部静态变量,即使在函数调用结束时也不释放空间(这一点不同于标准C语言)。Cx51编译器按照用户的设置,将所有的变量存放在片内和片外的RAM中。片内变量分配好空间后,将剩下的空间全部作为堆栈空间,这个空间是最大可能的堆栈空间。当然,因为Cx51是一种可以访问寄存器的C语言(特殊功能寄存器),因此可在程序中访问SP,将堆栈空间设置得小一点。不过,一般没有人这么做。本文只是讨论放在片内RAM的变量。我们把变量分为两种情况:

  ① 用作函数的参数和函数返回值的局部变量。这种变量尽量在寄存器组中存放。为了讨论方便,假设统一用寄存器组0,具体的地址为0x00~0x07。最多可以传递3个参数,如果参数的个数比较多,就将多余的参数放到内存(0x08以后的地址)中存放。这里,假设每个函数的参数都不大于3个。

  ② 我们在程序中定义的全局变量,以及不是用作函数的参数和函数返回值的局部变量。以上两种变量在内存中0x08地址以后存放,存放完毕后将堆栈指针SP指向分配了变量的片内RAM的最后一个字节。因为MCS51单片机的堆栈是一种满递增堆栈且堆栈的宽度为8位,所以在需要压栈操作时将堆栈指针先加1,后入栈有效内容。有了以上规则,就可以精确地计算出系统分配给用户的堆栈空间。以求两个数的最大公约数和最小公倍数的函数为例,代码如下:

  #include REG52.H>

  unsigned char max(unsigned char a, unsigned char b);

  unsigned char min(unsigned char a, unsigned char b);

  unsigned char M;

  void main (void) {

  unsigned char n;

  M = max(12, 9);

  n = min(12, 9);

  }

  unsigned char max(unsigned char a, unsigned char b){

  while(a != b) {

  if(a > b)

  a = a - b;

  else

  b = b - a;

  }

  return a;

  }

  unsigned char min(unsigned char a, unsigned char b){

  unsigned char k;

  k = a*b/M;

  return k;

  }

这段程序中资源的分配情况如下:一个全变量M(无符号字符型)存放最大公约数;主函数中定义一个局部变量n(无符号字符型)存放最小公倍数;求最大公约数的函数unsigned char max(unsigned char a, unsigned char b),有两个参数a和b;求最小公倍数的函数unsigned char min(unsigned char a, unsigned char b),有两个参数a和b,并且定义了一个变量k存放函数的返回值。可以由此计算出系统分配给变量的空间。函数的参数和返回值在工作寄存器组中存放,所以不占用0x08地址以后的空间。系统只给变量M和变量n分配存储空间,这两个变量占两个字节(地址为0x08和0x09),则堆栈指针SP应该指向0x09。Cx51系统编译后生成代码的系统资源占用情况如下:全局变量M的地址为0x08,n的地址为0x09,SP的值为0x09。这与我们的计算结果相符。

  3计算用户需要堆栈的大小

  堆栈区到底留多大才算足够呢? 设计中,用户需要堆栈的大小可以从普通子函数和中断子程序的嵌套层数来计算。普通子函数的调用比较简单,每次调用时就是将函数的返回地址保存在堆栈中,这个地址占两个字节。函数嵌套调用时,从最内层的子函数算起,总的堆栈需求字节数为嵌套的层数乘以2。中断子程序的堆栈需求分为两种情况:

  ① 中断子程序使用中断发生前的寄存器组。在中断发生时,保存中断子程序的返回地址需要2个字节。中断发生后,在中断子程序中系统会自动进行如下操作:将ACC、B、DPH、DPL、PSW、R0~R7共13个寄存器压栈。加上中断返回地址,中断的堆栈需求为15个字节。

  ② 中断子程序使用自己专用的寄存器组。这种情况下不需要保存R0~R7的内容,可以减少堆栈需求,其他的内容仍需要压栈保护。中断发生时,保存中断子程序的返回地址需要2个字节。中断发生后,在中断子程序中系统会自动进行如下操作:将ACC、B、DPH、DPL、PSW共5个寄存器压栈。加上、中断返回地址,这种堆栈的需求为7个字节。但是这种情况应该注意:如果中断子程序中调用子函数,且函数需要参数和返回值,则被调用的子函数和中断子程序要使用相同的寄存器组,否则会出现不可预料的后果。以一个温度测试系统为例。系统采用8051作为处理器,温度信号在A/D转换结束后通过外部中断0提醒单片机接收处理。定时中断0作为监控程序,中断周期为20 ms。温度信号可以自动测量(每秒一次)或者手动测量(按测量键后测量),这两种测量方法可以通过控制键切换。中断子程序和普通子函数的嵌套情况为:在定时中断程序中调用显示子程序,外部中断0内部没有函数调用。部分程序如下:

  void int0(void) interrupt 0 using 1 {

  读取转换数据;

  数据处理;

  }

  void time0 (void) interrupt 1 {

  计数值重装;

  读键;

  按键处理;

  leddisp(adat);//显示

  }

  void main (void) {

  相关数据初始化和数码显示自检;

  外部中断和定时器初始化设置;

  单片机休眠;

  }

  void leddisp(unsigned char *pt) {

  用串口工作方式0发送显示数据,并经过74LS164转换后静态显示;

  }

  接下来分析这段程序的最大堆栈需求。假设定时器0中断时,调用了显示函数void leddisp(unsigned char *pt),在调用显示函数时A/D转换结束发生了外部中断0的中断。这时应该是程序对堆栈的最大需求,堆栈的大小是:定时器0(15字节)+显示函数(2字节)+外部中断0(7字节)=24字节。

  结语

  通过精确的计算编译系统分配给用户的堆栈空间和用户自己最大的堆栈需求,不仅能从根本上解决堆栈溢出的问题,还可以很好地安排单片机比较紧张的资源。此外,通过在片内存储器存放适量局部变量,还可以有效地提高软件的执行速度。



评论


相关推荐

技术专区

关闭
脉浮是什么意思 前戏是什么 结肠炎吃什么药治疗效果好 嫩牛五方什么意思 玉如意什么属相不能戴
女人为什么会叫 女人梦见烧纸什么预兆 耳朵疼吃什么消炎药 头发长不长是什么原因怎么办 做深蹲有什么好处
冬至有什么禁忌 八月二十六是什么星座 为什么会长胎记 脸过敏发红痒擦什么药 一花一世界一叶一菩提什么意思
雪菜是什么菜 走四方是什么生肖 canon什么牌子 百香果不能和什么一起吃 三书六礼指的是什么
知行合一什么意思hcv8jop6ns7r.cn 为什么身上会长脂肪瘤hcv7jop6ns9r.cn 见利忘义是什么意思hcv8jop3ns5r.cn 刮痧不出痧是什么原因hcv7jop9ns7r.cn 炼乳可以做什么美食hcv8jop8ns6r.cn
草木皆兵是什么生肖hcv8jop2ns4r.cn 血小板计数偏高是什么意思hcv8jop6ns7r.cn 榆字五行属什么sscsqa.com 心率不齐是什么原因hcv8jop0ns3r.cn 梅尼埃病是什么病hcv8jop7ns9r.cn
一直放臭屁是什么原因hcv8jop5ns2r.cn 过敏性荨麻疹吃什么药hcv9jop3ns5r.cn 三眼花翎是什么意思hcv8jop6ns4r.cn 中央组织部部长什么级别hcv8jop4ns7r.cn 手机壳买什么材质的好hcv8jop6ns4r.cn
kr是什么货币hcv7jop6ns9r.cn 一日三餐是什么意思fenrenren.com 风热感冒吃什么药最好hcv8jop6ns5r.cn 专辑是什么hcv8jop6ns4r.cn 朱元璋属什么生肖hcv9jop5ns9r.cn
百度