main函数之前究竟发生了什么?
来源:互联网 发布:网络被帖子攻击怎么办 编辑:程序博客网 时间:2024/05/06 14:01
//=====================================================================
//TITLE:
// main函数之前究竟发生了什么?
//AUTHOR:
// norains
//DATE:
// Friday 3-December-2010
//Environment:
// MDK 4.1
//=====================================================================
当使用MFC时,我们会认为入口函数是:: InitInstance;当使用WIN32 API时,我们会认为入口函数是WinMain;当我们写个纯粹的C++程序时,入口函数又变成了main;可当我们进入到嵌入式领域,却发现main函数之前还有一段启动代码!
究竟在main函数之前,发生了什么?如果你觉得已经明白了这个过程,那么请试着回答这个问题:程序是存储到FLASH中的,运行时static变量地址是指向RAM,那么这些static变量的初始值是如何映射到RAM中的?
我们以STM32F10x的启动代码为例,先看看其完整的源码:
一些旁枝末节和本文的主题无关,我们先不要去理会,只需要知道这个启动代码是设置向量表,然后跳转到__main函数。跳转具体到代码段部分如下:
当大家看到__main函数时,估计应该有不少人认为这个是main函数的别名或是编译之后的名字,否则在启动代码中再也无法找到和main相关的字眼了。可事实是,__main和main是完全两个不同的函数!如果这还不足以让你诧异,那么再告诉你另一个事实:你无法找到__main代码,因为这个是编译器自动创建的!
如果你对此还半信半疑,可以查看MDK的文档,会发现有这么一句说明:It is automatically created by the linker when it sees a definition of main()。简单点来说,当编译器发现定义了main函数,那么就会自动创建__main。
__main函数的出身我们基本搞清楚了,那么现在的问题是,它和main又有什么关系呢?其实__main主要做这么两件事:初始化C/C++所需的资源,调用main函数。初始化先暂时不说,但“调用main函数”这个功能能够让我们解决为什么之前的启动代码调用的是__main,最后却能转到main函数的疑惑。
初始化C/C++所需的资源,如果脱离了具体情况,实在很难解释清楚,还是先看看编译出来的汇编代码片段:
凡是以__rt开头的,都是用来初始化C/C++运行库的;而以__scatterload开头,则是根据离散文件的定义,将代码中的变量映射到相应的内存位置。而回答本文开头的问题,关键就在于__scatterload_copy函数!
我们在STM32F10x平台举个简单的例子,首先要明白一点是,该平台的的flash地址以0x08000000为起始,主要是存储代码;而SRAM是以0x20000000为起始,也就是内存。然后C/C++有这么一行代码:
当我们程序开始跑起来的时候,通过IDE发现,g_iVal被映射到内存地址0x20000000,数值为一个随机数0xFFFFBE00,而不是代码中设置的12,如图:
我们让程序继续往下执行,当执行完毕__scatterload_copy之后,我们发现g_iVal这时候已经变成我们所需要的初始值了:
接下来就是C/C++库的初始化,最后就是进入到main函数,而此时已经是万事俱备。
如果大家只是局限于桌面应用的开发,因为编译出来的程序带有很多操作系统的特性,所以会给我们理解程序的运行带来很大的迷惑,也只有步入嵌入式领域,没有操作系统的支持下赤裸裸地奔跑在CPU之上,才能更好地理解软件是如何运行起来的,也只有这时候我们才能够更清楚知道,原来main函数并不是起点。
- main函数之前究竟发生了什么?
- main函数之前究竟发生了什么?
- main函数之前发生了什么
- iOS程序main函数之前发生了什么
- iOS程序main函数之前发生了什么
- iOS 程序 main 函数之前发生了什么
- iOS程序main函数之前发生了什么
- main函数之前都执行了什么?
- main函数之前做了什么?
- main函数之前做了什么?
- 进入main函数之前做了什么?
- 运行库:程序进入main()之前发生了什么
- main函数执行前发生了什么
- 程序在main函数之前做了什么
- main函数之前编译器都为你干了什么?
- main()之前都作了什么
- main函数之前会执行什么?
- 什么会在main函数之前执行
- 学习方法
- 自己动手编写的jquery插件,模仿搜狐汽车图片库展示效果
- arm-elf工具链的建立
- 模板的特化与偏特化
- 恐怖QQ聊天记录【常玩QQ的,胆小的别看】
- main函数之前究竟发生了什么?
- vc 对话框程序里,如何在密码输入框显示为****,屏蔽掉密码
- Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法
- c# 文件操作 对文件的添加 修改 删除
- 选择适合中国国情的信息防泄漏解决方案
- KDE上启用policykit
- 记得上次打架
- 一种分布式自治物流信息系统构架
- vmvare 配置