搜索
bottom↓
回复: 9

单片机堆栈问题.(这人多哦,就发这了)

[复制链接]

出0入0汤圆

发表于 2010-7-20 20:50:04 | 显示全部楼层 |阅读模式
今天调C8051单片机程序的时候,发现在子程序调用时,压入堆栈中的数据在子程序执行过程中被改变了,并且其中没有单独对该RAM单元进行操作……然后返回到不正确的位置,这真是太奇怪了……有大侠碰到这类情况的么? 用的Silab公司的编译器.

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2010-7-20 21:33:47 | 显示全部楼层
调用函数(ACALL)必然会压栈PC,两个字节。函数返回(ret)的时候出栈PC

这是51框架结构决定的,跟具体的芯片没关系。

silabs也不出编译器,只出了开发环境,编译器还是keil的。

出0入0汤圆

 楼主| 发表于 2010-7-20 21:37:14 | 显示全部楼层
哦 说错了 就是开发环境。我是说 已经压栈的PC值 在59H 60H 2个单元,在函数没有返回59H就被修改了.然后RET时返回到错误的地址

出0入0汤圆

发表于 2010-7-20 22:06:18 | 显示全部楼层
你修改startup文件了么

你的堆栈怎么都到了59H 60H了。

你在你程序开始的时候看一下SP的值是多少。

怎么用了这么大的堆栈空间。

出0入0汤圆

发表于 2010-7-20 22:18:54 | 显示全部楼层
startup的 stack段 默认是这样的

?C_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

也就是只保留了一个字节,好像默认SP是0xff,在ram用不了多少的情况下不会出现问题(堆栈从上往下,内存分配从下往上)。

但是如果内存用的比较多可能就出问题了,有一个办法是改变stack段的大小,但是这样可能链接过不了(报告内存不够)。

本来想把idata改成xdaga,好象不行,毕竟sp就是一个8位的地址。

aaa1982

出0入0汤圆

发表于 2010-7-20 23:23:41 | 显示全部楼层
【4楼】 aaa1982
积分:395
派别:
等级:------
来自:
startup的 stack段 默认是这样的

?C_C51STARTUP   SEGMENT   CODE
?STACK          SEGMENT   IDATA

                RSEG    ?STACK
                DS      1

也就是只保留了一个字节,好像默认SP是0xff,在ram用不了多少的情况下不会出现问题(堆栈从上往下,内存分配从下往上)。

但是如果内存用的比较多可能就出问题了,有一个办法是改变stack段的大小,但是这样可能链接过不了(报告内存不够)。

本来想把idata改成xdaga,好象不行,毕竟sp就是一个8位的地址。

aaa1982




堆栈从上往下是谁教你的?把他找来打残先,不光侮辱你智商还侮辱你人格.

出0入0汤圆

 楼主| 发表于 2010-7-21 00:02:23 | 显示全部楼层
TYPE    BASE      LENGTH    RELOCATION   SEGMENT NAME
            -----------------------------------------------------

            * * * * * * *   D A T A   M E M O R Y   * * * * * * *
            REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
            DATA    0008H     0001H     UNIT         ?DT?S_SOFTRESET?SHT10
                    0009H     0017H                  *** GAP ***
            BIT     0020H.0   0000H.1   UNIT         _BIT_GROUP_
                    0020H.1   0000H.7                *** GAP ***
            DATA    0021H     003EH     UNIT         _DATA_GROUP_
            IDATA   005FH     0001H     UNIT         ?STACK

         这貌似是系统自动生成的,感觉silab的开发环境不好用

出0入0汤圆

发表于 2010-7-21 09:26:45 | 显示全部楼层
回复【5楼】rainyss
-----------------------------------------------------------------------

说话太损了哈. 不过确实我说错了.

昨天手头没有程序,我想当然的就认为系统默认把SP放到了Idata的顶部,堆栈是递减的.(有什么是这样的结构么?感觉和什么弄混了)


今天找了个简单的试了一下

            REG     0000H     0008H     ABSOLUTE     "REG BANK 0"
            DATA    0008H     0019H     UNIT         _DATA_GROUP_
            DATA    0021H     0004H     UNIT         ?DT?MAIN
            IDATA   0025H     0001H     UNIT         ?STACK

确实堆栈的递增的. 不好意思误导了一下.


回复【2楼】gibson08
哦 说错了 就是开发环境。我是说 已经压栈的pc值 在59h 60h 2个单元,在函数没有返回59h就被修改了.然后ret时返回到错误的地址
-----------------------------------------------------------------------

1) 带H的应该是16进制吧.(怎么会59H 60H呢,是0x5f,0x60吧)

2) 如果按照你给的map文件,STACK 的范围应该从0x5f(95)开始,存两个地址。现确认这个是正确的吧。你链接的时候有警告么?

出0入0汤圆

 楼主| 发表于 2010-7-21 10:34:08 | 显示全部楼层
回复【7楼】aaa1982
-----------------------------------------------------------------------

嗯 写错了 5FH
warning C500: LICENSE ERROR (R208: RENEW LICENSE ID CODE (LIC))
这一个警告怎么解决? KEIL在网上下的破解,并且有运行成功的程序。

出0入0汤圆

发表于 2010-7-21 11:30:14 | 显示全部楼层
呵呵

不会是keil故意捣乱吧,你方便把程序发上来么,或者直接拿uvision 编译连接一下试试。

这么看不应该出现你说的问题。能定位到哪里修改的STACK么?你的意思是sp没有被改变,但是stack的值改变掉了,是这个意思么?

能定位到那句话改变你的stack的变量了么?
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 17:30

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表