单片机堆栈问题.(这人多哦,就发这了)
今天调C8051单片机程序的时候,发现在子程序调用时,压入堆栈中的数据在子程序执行过程中被改变了,并且其中没有单独对该RAM单元进行操作……然后返回到不正确的位置,这真是太奇怪了……有大侠碰到这类情况的么? 用的Silab公司的编译器. 调用函数(ACALL)必然会压栈PC,两个字节。函数返回(ret)的时候出栈PC这是51框架结构决定的,跟具体的芯片没关系。
silabs也不出编译器,只出了开发环境,编译器还是keil的。 哦 说错了 就是开发环境。我是说 已经压栈的PC值 在59H 60H 2个单元,在函数没有返回59H就被修改了.然后RET时返回到错误的地址 你修改startup文件了么
你的堆栈怎么都到了59H 60H了。
你在你程序开始的时候看一下SP的值是多少。
怎么用了这么大的堆栈空间。 startup的 stack段 默认是这样的
?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA
RSEG ?STACK
DS 1
也就是只保留了一个字节,好像默认SP是0xff,在ram用不了多少的情况下不会出现问题(堆栈从上往下,内存分配从下往上)。
但是如果内存用的比较多可能就出问题了,有一个办法是改变stack段的大小,但是这样可能链接过不了(报告内存不够)。
本来想把idata改成xdaga,好象不行,毕竟sp就是一个8位的地址。
aaa1982 【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
堆栈从上往下是谁教你的?把他找来打残先,不光侮辱你智商还侮辱你人格. 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的开发环境不好用 回复【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)开始,存两个地址。现确认这个是正确的吧。你链接的时候有警告么? 回复【7楼】aaa1982
-----------------------------------------------------------------------
嗯 写错了 5FH
warning C500: LICENSE ERROR (R208: RENEW LICENSE ID CODE (LIC))
这一个警告怎么解决? KEIL在网上下的破解,并且有运行成功的程序。 呵呵
不会是keil故意捣乱吧,你方便把程序发上来么,或者直接拿uvision 编译连接一下试试。
这么看不应该出现你说的问题。能定位到哪里修改的STACK么?你的意思是sp没有被改变,但是stack的值改变掉了,是这个意思么?
能定位到那句话改变你的stack的变量了么?
页:
[1]