因为我们通常在BOOTLOADER中都已做好了比较细致的初始化工作,包括代码的搬运,所以我们最好别再调用库函数__main(),因为__main()作为ADS集成好的库函数,会对系统进行初始化设置,可能会与我们的初始化发生冲突,故在我们做好初始化后最好别调用__main()。仿真时若调了__main()且没设置entry会报警告,__main()库函数代码不太了解,估计跟ADS初始化有关,库函数__main()要慎用。

    当所有的系统初始化工作完成之后,就需要把程序流程转入主应用程序,即呼叫主应用程序。最简单的一种情况是:
    IMPORT   main
    B            main
   
    直接从启动代码跳转到应用程序的主函数入口,当然主函数名字可以由用户随便定义。
    在ARM ADS环境中,还另外提供了一套系统级的呼叫机制。
    IMPORT   __main
    B            __main
 
    __main()是编译系统提供的一个函数,负责完成库函数的初始化和初始化应用程序执行环境,最后自动跳转到main()。所以说,前者是库函数,后者就是我们自己编写的main()主函数;
 
    因此我们用的B __main其实是执行库函数,然后该库函数再调用我们的main() 函数,因此在单步调试时会看到先要跑一段程序(其实是库函数),然后再单步到我们自己的main函数(这个同时也说明如果有B __main 则就对应必须有main函数,否则编译出错),如果我们用 B main来进入我们的主函数的话,那在单步调试时就看到直接进入到我们自己的main函数了,中间不会看到其他程序;

    那么用B __main和用B main 这两这进入我们的main函数方式有什么不同呢?
    如果采用前者则会由编译器加入一段"段拷贝"程序,即我们说的从加载域到执行域转化程序;而采用后者就没有这个了,因此如果要进行 "段拷贝"只能自己动手编写程序来实现了,完成段拷贝后就可以进入我们的主函数了,当然这个主函数不一定是叫做main(),可以起个其他好听的名字,这个有别于使用B __main方式;不管采用哪种方式进入我们的程序,都要有一段"段拷贝"程序,跑完了段拷贝后才能可以进入我们主程序了!(顺便提一下:startup.s这个文件并没有所谓的"段拷贝"功能,再看也无益!)
 
    对含有启动程序来说,"执行地址与加载地址相同"不容易实现:
    如果执行地址与加载地址相同哪当然不需要做"段拷贝",但是个人理解编译器还会加入"段拷贝"程序(如果用B __main的话),只是因为条件不满足而不执行而已;但是对含有启动程序来说,"执行地址与加载地址相同"就不容易了.因为启动程序是要烧到非易失存储器里,用来在上电执行的,而这个程序必定会有RW段,如果RW放在非易失存储器,如FLASH,那就不好实现RW功能了,因此要给RW移动到能够实现RW功能的存储器,如SRAM等.因此,对含有启动程序来说,"执行地址与加载地址相同"就不容易实现;程序的入口点在C 库中的__main 处,在该点,库代码执行以下操作:

1. 将非零(只读和读写)运行区域从其载入地址复制到运行地址。
2. 清零ZI 区域。
3. 跳转到__rt_entry。

__main() 和 main() 【转】的更多相关文章

  1. STM32_从SystemInit、__main到main()

    STM32 的 SystemInit() 和 __main Author by [YuCloud](https://www.cnblogs.com/yucloud/) 上篇文章 STM32启动代码分析 ...

  2. STM32 Startup**.s文件中使用的 __main C函数入口

    代码: ; Reset handler Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main L ...

  3. KEIL MDK输出map文件分析

    一.文件分析流程 1.第一部分:Section Cross References 主要是各个源文件生成的模块之间相互引用的关系. stm32f10x.o(STACK) refers (Special) ...

  4. STM32的例程GPIO的汇编指令初探

    任务一:寻找main函数的汇编指令集 任务二:寻找main函数中的SystemClock_Config函数的汇编指令集 寻找main函数的汇编指令集 运行例程中GPIO工程时,总会加载startup_ ...

  5. S3C2440启动代码2440init.s彻底解析

    可以选择nand启动和nor启动,这两者之间的关系通过一个按键来选择 这个OM0有何玄机,在数据手册中有这么一段 位宽RAM启动了(当然,还得设置一些东西,下面就说), Nanaflash启动经历的过 ...

  6. 启动文件startup_stm32f40_41xxx.s

    一.启动文件,startup_stm32f40x_41xx.s 1.定义 启动文件由汇编编写,是系统上电复位后第一执行的程序. Stack_Size EQU 0x00000400 // 栈的大小可以调 ...

  7. i.MX rt 系列微控制器的学习记录

    杂记 前言 我总是很希望自己能产生一种感知电压变化的能力,就像B站上的教学动图中,电流从电源流出时导线就像LED亮起来一样,我将指尖触到导线上就能感受到实时的电压变化.我在上学和工作时经常由于无法理解 ...

  8. python中 __name__及__main()__的使用

    python中 __name__及__main()__的使用 #hello.py def sayHello(): str="hello" print(str); if __name ...

  9. Java Main如何被执行?(转)

    java应用程序的启动在/hotspot/src/share/tools/launcher/java.c的main()函数中,而在虚拟机初始化过程中,将创建并启动Java的Main线程.最后将调用JN ...

随机推荐

  1. 导入java项目时出现红色叹号问题的解决

    问题:导入java项目时出现红色叹号(如下图所示) 原因:引入项目的某些jar包跟自己电脑上的位置不一样: 解决方案:步骤如下 (1)右键红色叹号所在项目————>build path————& ...

  2. Unity应用架构设计(11)——一个网络层的构建

    对于客户端应用程序,免不了和远程服务打交道.设计一个良好的『服务层』能帮我们规范和分离业务代码,提高生产效率.服务层最核心的模块一定是怎样发送请求,虽然Mono提供了很多C#网络请求类,诸如WebCl ...

  3. re 学习随便

    . 任意一个字符 \转义字符 *  字符重复0--多次 + 字符重复1-多次 ? 字符重复0-1次 ^行首匹配 或者在一个字符集中表示取反 \$  匹配字符串末尾 \b 匹配\w 与\w 之间的 \B ...

  4. 用excel公式生成有规律的代码,减少编程工作量

    1.在excel中如何输入公式 在excel表格中输入 & 符号是字符串的连接符,比如: 在excel表格中输入  ="sherlock"&"mina&q ...

  5. Thinkphp模板的使用

    模板标签 内置标签:include,import,volist,foreach,for,switch,compare,present,empty,defined,if/else 输出php代码:PHP ...

  6. window对象screen、history

    Window 对象属性 http://www.runoob.com/jsref/obj-window.html

  7. BOM API

    原文链接http://www.jb51.net/article/55851.htm 我们都知道, javascript 有三部分构成,ECMAScript,DOM和BOM,根据宿主(浏览器)的不同,具 ...

  8. Angularjs在360兼容模式下取数据缓存问题解决办法

    测试提了一个bug,在360浏览器兼容模式下,删除页面数据需要手动刷新浏览器才能看到最新的数据.首先要复现当时的问题,很容易就复现了,但是发现在360浏览器兼容模式下无法打开开发者工具.好在经过反复重 ...

  9. 如何给两个swiper建立关系

    单个swiper已经满足不了需求了. 各种花式轮播已经慢慢进入市场.swiper该如何立足,那么请看. <div class="swiper-container"> & ...

  10. httpClient 发送请求后解析流重用的问题(HttpEntity的重用:BufferedHttpEntity)

    使用场景: 项目中使用httpClient发送一次http请求,以流的方式处理返回结果,开始发现返回的流只能使用一次,再次使用就会出错,后来看了一些解决方案,EntityUtils.consume(r ...