OpenEdv-开源电子网

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

分享一下关于启动文件的看法

[复制链接]

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2016-4-30
在线时间
44 小时
发表于 2016-9-18 23:14:34 | 显示全部楼层 |阅读模式
本帖最后由 stayhungry 于 2016-9-18 23:14 编辑

大四狗等待秋招中,无聊之下就开始了学习M3的底层,现在分享一下,给予像我一样的新人一些帮助。
这次的研究的总结:划分“栈”这个动作是在编译器实现的,芯片刚复位上电时自己没有栈的概念(它甚至不知道自己的内存地址从哪里开始),所以也不会划分,编译器告诉它哪里是栈,哪里就是栈。(对于M3,是通过将栈顶地址放进0x00000000来通知芯片自己栈在哪里)。后来想起了之前度娘“栈和堆的区别”经典文章有提到过栈和编译器的关系更加验证了我的想法。好了,废话不说,入主题。



以下是用来验证想法的汇编程序,参考的是STM32的启动文件。
                                AREA   USER_STACK, NOINIT, READWRITE               ;定义一个段叫USER_STACK,用来当栈
                                SPACE        0X00000400                                   ;分配一段空间作为栈              
MSP_TOP                                                                                            ;栈顶地址

                                AREA        RESET, DATA, READONLY
                                DCD     MSP_TOP                          ; ①

                                END


遇到的疑惑和一些猜想:
1、对于M3,怎么理解“编译器划分栈”这个概念?
    答:
   这里以keil5为例,先将环境配置成平时码F1程序的环境,然后工程文件用上面的汇编程序和一个干净的main函数.c文件。将Debug的Run to main()取消掉,编译之后运行软件仿真打开内存监视窗口 QQ图片20160918211326.png

因为M3会把0x00000000映射到0x08000000,所以0x08000000内容就是0x00000000的内容,根据《M3权威指南》知道,刚上电之后在0x08000000的第一个数值就是栈的栈顶,也就是上述程序RESET段的MSP_TOP。所以这里的栈顶地址就是0x20000460,可以通过查看map文件 QQ图片20160918212211.png 来证明MSP_TOP这个标号代表的地址是0x20000460。那么这个0x20000460是怎么来的呢?其实它是0x20000000+400h+60h,0x20000000就是栈开始划分的地址,是我们在Option->target->IRAM1设置的,这是我通过多次改变IRAM1的数值,对比观察仿真结果发现的。400h就是栈的大小,就是我们在汇编开头写的SPACE 0x00000400,如果你在SPACE指令之前写一个分配4字节内存的指令(DCD 0)会发现这里的400h会变成404h,通过查看map文件看到, 1.png ,USER_STACK这个段比之前多了4字节,这也就是为什么网上资料说更改这个SPACE后面的数值就是改变栈的大小,其实只要在USER_STACK段里面,分配了多少内存(必须小于Option->target->SIZE),栈就有多大。至于这个60h我也不清楚是什么,好像和静态变量初始化有关,想深究的可以看我之前的求助帖,里面有个网站说明。

所以对于M3,“编译器划分栈”的概念就是    IRAM1的数值+用户程序中需要的栈大小(必须小于Option->target->SIZE)+60h  从而得出一个栈顶地址
2、“栈”和芯片内存的关系?
答:
     上面汇编的①指令所处位置代表的意思就是告诉芯片:0x20000000~0x20000460这段内存我占用来做栈了。
         编译结果: Program Size: Code=288 RO-data=20 RW-data=0 ZI-data=1120                    占掉了RW+ZI= 0+1120 = 460h内存
     如果把汇编①指令注释掉,就没人告诉芯片哪里是栈了。
         编译结果: Program Size: Code=288 RO-data=20 RW-data=0 ZI-data=96                        占掉了RW+ZI=0+96=60h内存

这里说明了,占不占用芯片内存是由向量表第一项来决定的,而不是编译器是否已经划分了栈决定的。当然这样不要栈的程序写进芯片是非法的,不过只是想验证我的一些猜想,所以也就没关系了。

以上就是我从启动文件得出的一些看法,不足或出错之处还望指出。




start_up.zip

61.18 KB, 下载次数: 165

工程文件

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

13

主题

314

帖子

0

精华

高级会员

Rank: 4

积分
713
金钱
713
注册时间
2012-7-20
在线时间
102 小时
发表于 2016-9-18 23:26:26 | 显示全部楼层
回复 支持 反对

使用道具 举报

9

主题

538

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3371
金钱
3371
注册时间
2015-1-7
在线时间
794 小时
发表于 2016-9-19 08:31:02 | 显示全部楼层
支持一下
回复 支持 反对

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11537
金钱
11537
注册时间
2014-4-1
在线时间
1314 小时
发表于 2016-9-19 09:10:29 | 显示全部楼层

目测是原创。

回复 支持 反对

使用道具 举报

11

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
109
金钱
109
注册时间
2016-4-30
在线时间
44 小时
 楼主| 发表于 2016-10-4 17:16:43 | 显示全部楼层

啊哈~写这个帖子时候还不懂什么是栈和堆,map文件也不知道应该怎么看,就捣鼓捣鼓一下。后来看了原子哥的相关帖子和一些高人的见解,然后自己再捣鼓一下,对这些东西都有了深刻理解。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-25 19:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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