zoukankan      html  css  js  c++  java
  • keil mdk编译器学习笔记(2)

    1、默认情况下,keil和iar都是认为char是unsigned char,可以通过设置去更改的。


    2、赋初值的全局变量和静态变量,对于在程序中赋初值的全局变量和静态变量,程序编译后,MDK将这些初值放到Flash中,紧靠在可执行代码的后面。在程序进入main函数前,会运行一段库代码,将这部分数据拷贝至相应RAM位置。


    后来看ARM的链接器,才知道ARM映象文件各组成部分在存储系统中的地址有两种:一种是在映象文件位于存储器中时(也就是该映象文件开始运行之前,通俗的说就是下载到Flash中的二进制代码)的地址,称为加载地址;一种是在映象文件运行时(通俗的说就是给板子上电,开始运行Flash中的程序了)的地址,称为运行时地址。赋初值的全局变量和静态变量在程序还没运行的时候,初值是被放在Flash中的,这个时候他们的地址称为加载地址,当程序运行后,这些初值会从Flash中拷贝到RAM中,这时候就是运行时地址了。


    3、Stack分配到RAM的哪个地方? keil MDK中,我们只需要定义各个模式下的堆栈大小,编译器会自动在RAM的空闲区域选择一块合适的地方来分配给我们定义的堆栈,这个地方位于RAM的那个地方呢?通过查看编译列表文件,原来MDK将堆栈放到程序使用到的RAM空间的后面,比如你的RAM空间从0x4000 0000开始,你的程序用掉了0x200字节RAM,那么堆栈空间就从0x4000 0200处开始。具体的RAM分配,其实你可以从编译后生成的列表文件“工程名.map”文件中查看。


    4、编译过程中,尽量不用高优化,高优化会吧很多代码会优化掉,如果禁止优化,使用volatile关键字,尤其是中断里面用到的全局变量,定义和生命都要加volatile 关键字,编译器是分文件编译,然后链接,文件A使用了文件B中定义的变量,在编译的时候,文件A是完全不知道文件B里面有什么东西的,只能通过文件B的接口文件(.h文件)来获得使用变量的属性。

    不过目前使用新的编译器(我下载了keil mdk5.29),没有出现过类似bug,说明编译器越来越聪明了。


    5、关于float类型,keil中,网上有文章说,如果不开启Optimize for time,则会占用8字节,开启Optimize for time编译选项,则占用4字节,具体没有测试过。

    经过测试,上文说法已经不符合新版的keil了,相比keil4是这么特性,但是keil5.20我试过后,float只占4字节,与Optimize for time无关


    6、.默认情况下,从按下复位到执行你编写的C代码main函数,keil mdk做了些什么?


    之前开错rt-thread的启动代码,在main函数之前,就已经做了很多工作,其实在汇编文件startup_stm32f103xe.s中,已经做了很多工作。
    复位后,已经调用了SystemInit函数,其实可以做更多,这里在另一篇文章中再详细展开。
    ; Reset handler
    Reset_Handler PROC
    EXPORT Reset_Handler [WEAK]
    IMPORT __main
    IMPORT SystemInit
    LDR R0, =SystemInit
    BLX R0
    LDR R0, =__main
    BX R0
    ENDP
    最后才进入main函数。

  • 相关阅读:
    cf Round 633
    Django学习手册
    Django学习手册
    Django学习手册
    Django学习手册
    Django学习手册
    Django学习手册
    ERROR CL .exe……错误
    DLL、lib等链接库文件的使用
    HTTP协议
  • 原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/12119303.html
Copyright © 2011-2022 走看看