OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 23929|回复: 39

深夜兑诺言.简单的CortexM栈检查.

[复制链接]

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
发表于 2013-8-13 00:46:43 | 显示全部楼层 |阅读模式
RT,帖子是这个
http://www.openedv.com/posts/list/19244.htm

使用时,需要把栈底地址搞出来,比如STM32的官方启动代码里,在汇编里加入

EXPORT  Stack_Mem

即可.

代码里偶尔检查检查,可以知道是否出现栈溢出.

尽早食(使)用,风味更佳.






CortexM_StackCheck.c

1002 Bytes, 下载次数: 1044

CortexM_StackCheck.h

598 Bytes, 下载次数: 917

技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2013-8-13 09:57:10 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

109

主题

1606

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2222
金钱
2222
注册时间
2011-12-15
在线时间
37 小时
发表于 2013-8-13 11:50:40 | 显示全部楼层
这么晚都在刻苦,不容易呀。
专业制作STM32 物联网通信模块板,模块交流群:369840039。
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-13 12:22:43 | 显示全部楼层
最好能够检查堆栈使用量。
业余程序玩家。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 12:56:23 | 显示全部楼层
回复【4楼】ofourme:
---------------------------------
做不到,除非每次入栈都检查,这分明是内核做的事.

堆的使用量就好办,因为堆操作都是软件完成的,管理也是软件的事.只是如果需要实现,就要先自己先写一个内存管理的程序了.

打点擦边球是可以的,还是用上面的代码,只是把检查的空间充满整个栈,每次检查也是全盘检查,基本上可以得到栈的使用量,只是CPU占用就上去了.

为什么说是"每次检查",而不是只检查一次,是由于单片机通常没有主程序出口,所以只能五步一岗的查了.

小程序嘛,先解决无故hardfault的隐患吧.暗病变明病,对症下药才方便.后面检查容量就简单了,二分法试几个值就ok了.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-13 13:46:50 | 显示全部楼层
stm的系统栈是存放在内存的最顶端的,如果发生栈溢出的话一般就是fatul死机了。如果不是系统栈的话,建议还是用操作系统的堆栈检查功能。
业余程序玩家。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 18:40:51 | 显示全部楼层
回复【6楼】ofourme:
--------------------------------
是的,操作系统栈检查更方便.这个只是为了裸奔用.毕竟操作系统有操作系统的缺点,不是每个项目都用.

栈溢出不一定会死机,比如栈只生长到堆区,或者稍微进入变量区,而且溢出整个过程不对这些区域做写入操作,不对这些区域做取指操作,就可以完美避免hardfault,但溢出还是溢出了,数据还是被修改了.最"直接"的表现是函数调用后,还没看到执行用户代码就发现某些不相干的数据被修改,不过这也足够隐蔽了.

而且,hardfault也不一定是栈溢出的直接结果,只是入栈后数据被修改,出栈时跳转错误(最容易出现),导致指令访问错误,或者数据访问错误.

但查这些都是费时费力,因为没有指向性.要调整栈空间,也不知道调整多少才对,因为不一定hardfault给你看,但数据莫名修改是实实在在的.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-13 19:26:24 | 显示全部楼层
如果你用到多个堆栈的话(这个一般是有用到OS的情况了),你这个程序确实有用。

但是,考虑到非多任务的情况,具体到stm32来说,Stack_Mem的值是什么?是0x20000000,也即内部sram的起始地址,如果堆栈溢出并写数据的话,肯定是fault的。因为Stack_Mem之前已经不是有效的sram位置了,根本没有数据可以给你去修改了。

所以,除非你去修改Stack_Mem的位置,...
业余程序玩家。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 20:37:05 | 显示全部楼层
回复【8楼】ofourme:
---------------------------------
有OS反而不用了,因为基本OS都有栈检查.原理和这个一样.

Stack_Mem位置是由链接器决定的,LZ的头文件也写了,需要从栈配置文件导出,不一定是在RAM起始地址.比如MDK的内存分配,最后面是栈,栈前面是堆,堆前面是变量区.

当然,把栈加载到内存区的起始地址也可以做到溢出必进hardfault,要么在汇编增加绝对定位,要么修改分散加载文件.这就是个人风格问题了,我自己喜欢代码尽量通用,而且零修改重用.

这说到我写这个代码的原因,我一直以为栈是像你说的分配到内存的起始地址,结果有一天,我发现我错了...考虑到这里用MDK的用户基数,就放出来了.

这里是首发,也是唯一发表.

ps:堆是堆,栈是栈,虽然理解你说的是栈,但看着看着还是要转一下弯.

堆是必须通过代码只是分配的动态内存,C的malloc/calloc/free,C++的new/delete,还有原子写的,有专门函数负责分配和回收,可能还有一些维护函数,所管理的内存空间.

栈是无需用户自己调用指令申请的.栈不是完全硬件实现,完全硬件实现的是PC的出入栈,工作区的出入栈还是有具体的代码实现的,只是编译器会在变量使用前调用函数/指令入栈,生存期结束就出栈还原工作区.这些都不用用户实现,就像硬件自动完成那样.而且有些代码,比如
int func(void)//无优化编译
{
    int a = 1;
    int b = 2;
    return (a & 0x3) | (b * 4);
}
这种,栈的使用将会大于2*sizeof(int).

上面的代码在编译器优化过之后,就会变成消耗1*sizeof(int)的栈,用于直接赋值1,然后对其入栈返回.如果是堆,无论用户用不用,申请成功就拿到了,不想用的话,程序也不会自动回收.

这里不是指Java之类有垃圾回收的平台,这些平台是在中间层做了个壳,任何操作都有检查,所以代码操作安全而且低效.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-13 20:56:20 | 显示全部楼层
回复【9楼】shihantu:
---------------------------------
看来你是学计算机的。

arm的返回值,不超过4B的话,直接用R0,不用压栈的。估计不超过16B的话都可以通过R0~R3返回的。这个不像x86。

另,你说的“MDK的内存分配,最后面是栈,栈前面是堆,堆前面是变量区”,楼主真的确定吗?貌似跟我的认识不太一样哦!
业余程序玩家。
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-13 21:07:09 | 显示全部楼层
“完全硬件实现的是PC的出入栈”——看来楼主真的是把x86的经验套用到ARM来了。
x86的汇编程序我没写过,大概了解过一些罢了,但是,真的和ARM、51的汇编不一样。ARM有LR寄存器,单层调用的话根本没必要压栈,多层调用的话就要指令显式把LR压栈了。


不是针对楼主,纯粹技术讨论哦!
业余程序玩家。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 21:38:56 | 显示全部楼层
回复【11楼】ofourme:
---------------------------------
很抱歉,我也没有x86的经验.

这个PC是Program Counter,没说清楚不好意思.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 21:50:28 | 显示全部楼层
回复【11楼】ofourme:
---------------------------------
单层调用或者是多层调用,在ARM里分析比较简单,如果编译器认为可以内联,就自动内联了,跨文件的只能链接,不能内联,这个和x86反而有点区别,毕竟最终生成的是hex,直接面对内核译码.

不知道有没有编译器既能混联,同时保留原函数入口动态用于多层调用的情况.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 22:01:58 | 显示全部楼层
回复【10楼】ofourme:
---------------------------------
我是学材料的..

通过R传递返回值,我在51上研究过,ARM没有具体看,估计大同小异.

MDK的内存分布,我之前也不知道,后来是有个小隐患,才一直跟踪到.实际上map文件上标明了.估计链接器默认就是按照这个干活的吧,在汇编里HEAP和STACK都是关键字...不过提供了很多方式自定义堆栈空间是真的.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-13 22:08:28 | 显示全部楼层
刚看了,的确通过R0返回.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-14 12:29:10 | 显示全部楼层
回复【12楼】shihantu:

很抱歉,我也没有x86的经验.
这个PC是Program Counter,没说清楚不好意思.

---------------------------------

我知道PC指的是Program Counter啊。cortex-m3有个LR寄存器,进入函数的时候已经把R0~R3, LR等寄存器压栈了。在函数里调用函数的话,会把PC存到LR寄存器里,被调用的函数返回的时候,把LR的值送回PC就行了。以上行为都是要显式通过指令实现的(异常、中断例外)。arm对LR的这个设置确实挺巧妙的,x86在一个函数里面如果多次调用别的函数的话,就要多次压PC入栈,但是arm的话只需要在开始的时候吧LR入栈,调用函数的时候硬件自动把PC放到LR就行了,根本不用访问内存。不过x86上有cache,访问内存的速度应该也是挺快的。

另外,你说的MDK就是keil吧?keil4我没用过,但是站长提供的的keil3.7,从启动文件看,在不自定义statter文件的情况下,明明是默认把栈放在了内部SRAM的起始位置啊,我用的是mini板。难道你的不是吗?为什么你说从map看,“MDK的内存分配,最后面是栈,栈前面是堆,堆前面是变量区”呢?能把这个问题讨论清楚吗?
业余程序玩家。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-14 16:58:23 | 显示全部楼层
回复【16楼】 ofourme :
---------------------------------
附件是我的一个小工程的map,Heap和Stack在2358,3608行附近.

MDK版本是4.7,芯片是C8T6

"会把PC存到LR寄存器里,被调用的函数返回的时候,把LR的值送回PC就行了。以上行为都是要显式通过指令实现的"

说的就是这回事,这个没有异议吧.

我没有光顾过原子呢..有时想帮忙测试具体问题也帮不上..不过我自己用C++整了个库,也不太愿意敲解放前的代码了.

DataCollect.map

376.06 KB, 下载次数: 642

技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2013-8-14 17:57:51 | 显示全部楼层
回复【17楼】shihantu:
---------------------------------

看了一下,楼主是对的。
发现我犯了很严重的错误。谢谢LZ指正!
业余程序玩家。
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-8-15 00:15:36 | 显示全部楼层
回复【18楼】ofourme:
---------------------------------
可能是链接器的问题,旧的就不知道什么情况了,毕竟不会装个旧的为了看它的map.

我也不明白为什么不按你说的方法做,这样就省事很多.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-11-16 16:06:53 | 显示全部楼层
回复【4楼】ofourme:
---------------------------------
现在回来看你的这个问题,栈用量是可以检查的,只要把(*(uint32*)0x08000000)和MSP相减就可以了.

堆的话,还是比较麻烦,要么重载malloc和free,要么弄明白堆的结构算出来.前者有有办法整到吗?我查了好久都没有找到.后者有点吃力不讨好,什么时候编译器更新一下就无效了.我现在是用c++,可以重载new和delete,但用到标准库和内部协议栈什么的还是无解,白白多开一个管理空间.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2013-11-16 18:10:09 | 显示全部楼层
回复【20楼】shihantu:
---------------------------------
用__get_MSP,比较安全。
__asm uint32_t __get_MSP(void)
{
  mrs r0, msp
  bx lr
}

对于新版本的.s文件,0X0800 0000存储的是__initial_spTop的值(hd.s为0x20000400),而不是我们后续用的MSP值。

对老版本的.s文件,用0X0800,0000存储的值,是OK的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2013-11-16 19:09:27 | 显示全部楼层
回复【21楼】正点原子:
---------------------------------
获取当前栈指针可以用__get_MSP.

关于栈空间的获取,19L的确大意了,没有考虑HD启动文件里使用双栈指针的情况.

这里应该把__initial_sp也输出出来才正确.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 11:40:23 | 显示全部楼层
回复【6楼】ofourme:
---------------------------------
stm的系统栈是存放在内存的最顶端的

那就是栈顶在0x20000000+20k(RAMSIze)=0x20005000?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 12:21:03 | 显示全部楼层
回复【20楼】shihantu:
---------------------------------
(*(uint32*)0x08000000)=__initial_sp

   栈用量是可以检查的,只要把(*(uint32*)0x08000000)和MSP相减就可以了. 

弱弱的问一下__initial_sp是不是栈底?MSP是不是目前使用到的地方,比如栈底__initial_sp 0x20007C00 初始化栈顶MSP=0x20008000,入栈一个元素后MSP就变成0x20007FFC。是这样理解么?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 12:29:52 | 显示全部楼层
LZ在另一个帖子看了你和原子哥关于堆栈的讨论,比较菜没看太懂,再多问一下。
比如我的RAM 20k
内存组织是:静态区+堆+栈
我的Stack_Size      EQU     0x00000400      1k
      Heap_Size       EQU     0x00000200      0.5k
 
栈顶是不是就该0x2000 0000 +20k=0x2000 8000
栈底就是0x2000 8000 - 0x00000400   
堆是向上增长,起始位置:   0x2000 8000 - 0x00000400 -  0x00000200  

这样理解对么?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 12:37:05 | 显示全部楼层
上面数字写错了。。。。
比如我的RAM 20k 
内存组织是:静态区+堆+栈 
我的Stack_Size      EQU     0x00000400      1k 
      Heap_Size       EQU     0x00000200      0.5k 
  
栈顶是不是就该0x2000 0000 +20k=0x2000 5000 也就是__initial_sp 
栈底就是0x2000 5000 - 0x00000400    
堆是向上增长,起始位置:   0x2000 5000 - 0x00000400 -  0x00000200   就是__heap_base?

这样理解对么
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2014-3-14 12:39:08 | 显示全部楼层
回复【23楼】wwjdwy:
---------------------------------
建议看一下自己工程的map文件.

回复【24楼】wwjdwy:
---------------------------------
当前用量检查可以这么做,用于定位栈溢出的位置等.
Cortex的栈是向下生长的,__initial_sp是栈顶.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 14:57:49 | 显示全部楼层
回复【27楼】shihantu:
---------------------------------
MSP是当前程序栈增长到的地方?__initial_sp-MSP就是已使用的栈的量了,对吧。

追问一个关于Heap_Size       EQU     0x00000200,我要使用堆必须用malloc,自己实现这个函数,然后定位到heap的区间来用?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 15:20:52 | 显示全部楼层
回复【27楼】shihantu:
---------------------------------
==============================================================================


      Code (inc. data)   RO Data    RW Data    ZI Data      Debug   

     39562       2998       3550        292       2108     641228   Grand Totals
     39562       2998       3550        292       2108     641228   ELF Image Totals
     39562       2998       3550        292          0          0   ROM Totals

==============================================================================

    Total RO  Size (Code + RO Data)                43112 (  42.10kB)
    Total RW  Size (RW Data + ZI Data)              2400 (   2.34kB)
    Total ROM Size (Code + RO Data + RW Data)      43404 (  42.39kB)

==============================================================================

栈顶位置是从这看么?堆区能看出来么
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2014-3-14 17:58:46 | 显示全部楼层
回复【28楼】wwjdwy:
---------------------------------
是.
不用,keil已经实现了malloc和free功能,虽然不爽.

回复【29楼】wwjdwy:
---------------------------------
map全文搜索__initial_sp,heap和stack三个标号.
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 18:20:23 | 显示全部楼层
回复【30楼】shihantu:
---------------------------------
   __initial_sp                             0x20000960   Data           0  startup_stm32f10x_md.o(STACK)
STACK                                       0x20000560   Section     1024  startup_stm32f10x_md.o(STACK)

STACK是栈底么?__initial_sp-STACK   = 0x 400     
Stack_Size      EQU     0x00000400  
个人猜测哈  

Image Symbol Table

    Local Symbols  指的是局部变量吧

Removing Unused input sections from the image.
 Removing startup_stm32f10x_md.o(HEAP), (512 bytes).
是不是我没有malloc所以没有给我分配这512bytes?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 18:36:09 | 显示全部楼层
在函数中用了一下malloc试验了一下:
int *p=NULL;
p=malloc(sizeof(int));  

HEAP                                      0x20000568   Section      512  startup_stm32f10x_md.o(HEAP)
STACK                                    0x20000768   Section     1024  startup_stm32f10x_md.o(STACK)
 __heap_base                         0x20000568   Data           0  startup_stm32f10x_md.o(HEAP)
 __heap_limit                          0x20000768   Data           0  startup_stm32f10x_md.o(HEAP)
 __initial_sp                             0x20000b68   Data           0  startup_stm32f10x_md.o(STACK)

一目了然了,多谢高人指点啊
回复 支持 反对

使用道具 举报

70

主题

6761

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
13102
金钱
13102
注册时间
2012-11-26
在线时间
3811 小时
发表于 2014-3-14 18:45:25 | 显示全部楼层
mark
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 19:38:28 | 显示全部楼层
接着上一楼:
=============================================================================


Code (inc. data)      RO Data     RW Data     ZI Data     Debug

39770    3014          3550        300            2620         395376 Grand Totals
39770    3014          3550        44              2620         395376 ELF Image Totals (compressed)
39770    3014          3550        44                0             0 ROM Totals

==============================================================================

Total RO Size (Code + RO Data)                         43320 ( 42.30kB)
Total RW Size (RW Data + ZI Data)                    2920 ( 2.85kB)
Total ROM Size (Code + RO Data + RW Data)      43364 ( 42.35kB)

==============================================================================

在map中:

 Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Object Name 

36          8             236            0              1536          0         startup_stm32f10x_md.o

堆也在ZI中

再次查看RW之后发现多了这个:

Image component sizes 

Code (inc. data)   RO Data    RW Data    ZI Data      Debug   Library Member Name

      0          0          0                   8          0                 0              mvars.o

所以比之前的没加malloc时候总共多了512+8=520

ELF Image Totals (compressed)和Grand Totals之间RW少了256是什么意思?压缩了?求解
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2014-3-14 19:45:30 | 显示全部楼层
http://www.keil.com/support/man/docs/armlink/armlink_CACHFGGB.htm
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

2

主题

1446

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2246
金钱
2246
注册时间
2010-12-16
在线时间
202 小时
 楼主| 发表于 2014-3-14 19:45:44 | 显示全部楼层
回复【34楼】wwjdwy:
---------------------------------
技术讨论请发帖 , 需要我回复请点左下的 < 回复 > 让系统通知我 . 本人不通过其他方式返回任何参数.
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2014-3-14 19:56:08 | 显示全部楼层
回复【36楼】shihantu:
---------------------------------
ELF Image Totals
If you are using RW data compression (the default) to optimize ROM size, the size of the final image changes and this is reflected in the output from --info. Compare the number of bytes under Grand Totals and ELF Image Totals to see the effect of compression.

In the example, RW data compression is not enabled. If data is compressed, the RW value changes.

果然是被压缩了吼吼。
搞懂了哈哈。
太感谢了,总算把这些名词搞懂了呵呵呵
回复 支持 反对

使用道具 举报

26

主题

202

帖子

3

精华

高级会员

Rank: 4

积分
810
金钱
810
注册时间
2014-3-4
在线时间
11 小时
发表于 2014-3-14 20:05:52 | 显示全部楼层
MARK
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1865
金钱
1865
注册时间
2011-3-29
在线时间
140 小时
发表于 2014-3-15 22:53:46 | 显示全部楼层
回复【23楼】wwjdwy:

回复【6楼】ofourme:
---------------------------------
stm的系统栈是存放在内存的最顶端的
那就是栈顶在0x20000000+20k(RAMSIze)=0x20005000?

---------------------------------

我的意思是假如栈1k的话,栈顶就是0x20000000+1k=0x20000400。
但我上面的说法是不对的,shihantu说的才是正确的。
业余程序玩家。
回复 支持 反对

使用道具 举报

8

主题

136

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
428
金钱
428
注册时间
2015-4-24
在线时间
85 小时
发表于 2016-11-23 16:47:55 | 显示全部楼层
你好,问下如果我想看下栈的大小有没有溢出,想把 EXPORT  Stack_Mem加入到启动文件中,这句话是随便放到启动文件中还是有什么固定的位置。另外导出的值从哪里可以看到,是在map文件中吗,谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-25 10:00

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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