__main -> main
1.前言
上一篇博客详细地讲述了一个流程:
cpu执行第一条用户代码 -> 调用__main函数
这篇博客着重讲述了STM32启动文件中一些需要注意的细节,对于STM32启动文件的内容没有过多的讲解,因为我的第一篇博客讲述的就是STM32启动文件的解释。
而本篇博客将要详细地描述一个流程:
_ _main函数 -> __rt_entry -> main函数
这里再次声明一下:__main函数是c库中的一个函数,和用户编写的main函数是有区别的!!!
2.必备知识
必备知识中主要是用到了.map文件,双击红色箭头所指向的区域就可以打开!!!
2.1. 用户程序在FLASH中的组织架构
上面两张图截取了镜像文件在FLASH上的内存分布。
从上面两张图可以知道,在程序的最开始处,存储的是数据段,这个数据段就是中断向量表,里面存储这所有中断函数的入口地址。
紧跟着的就是代码段,代码段包含了自己编写的用户代码和库函数。
之后有跟着数据段,这个数据段有个专有的名称,叫做代码常量区,也就是你定义的const类型的全局变量(记住不是const类型的局部变量,const类型的局部变量还是存储在栈区)会存储在这个区域。
特别注意,非常重要的知识点:
在代码常量区后面还有一个区,叫做读写数据区,这个区域中的数据最终要被拷贝到SRAM中去,因为FLASH只能读不能写(事实上可以进行写操作,只不过需要密钥而已,参考手册中有说明)而SRAM中的数据是可读可写的。
但是,.map文件中并没有提到,也就是说你从.map文件中是找不到这个区的,
你能看到的最后一项就是代码常量区,因此这个地方一般情况下很难发现到,只有深入__main函数之后才可以知道。
值得注意的是:
在代码区中,不仅有Code、Data类型的数据,还有PAD!!!
PAD就是padding的意思,中文翻译过来就是填充的意思
作用:进行4字节对齐,提高cpu的取指速率
也就是说,无论是指令还是数据,在内存中都要4个字节对齐,所表现出来的特征就是: