美文网首页STM32
keil下的程序内存分布情况

keil下的程序内存分布情况

作者: lissettecarlr | 来源:发表于2019-06-13 00:07 被阅读0次

    之前一直没认真关注过这个,随心所欲地瞎比写,然后终于flash被写满了,于是才来研究下。

    keil在每次编译后都会打印各个区域的大小情况,例如下图。


    image.png

    并且会在那堆编译文件中生产一个.map的文件,里面详细列举了各个地址使用情况,翻到最后便能看到你实际flash的需求情况了。例如下图程序,实际使用的flash是123.96KB


    image.png

    然后简单说明一下各个区域代表的意思

    • Code表示的就是你的代码,其中不包含变量定义相关,而是逻辑部分。
    • RO-data是只读数据段,存放常量。那什么是常量呢,例如定义了int a=123,这123就是常量,需要被保存起来。宏定义不是常量,它是在编译前进行替换的。
    • RW-data读写数据段,用于存放已被初始化且初始化不为0的全局变量。还是上面的例程int a=123,他存放的便是int a。
    • ZI-data 0数据段,用于存放为被初始化或者初始化为0的全局变量。例如int a,那么a会被保存到ZI-data而不是RW-data。

    实际上我们存入flash中的数据包含的是 Code + RO-data + RW-data,是不包含ZI-data的。
    当程序运行时RW-data将从flash被搬运到内存中,然后再划分出ZI-data段并将其全部置零。
    这里借用一种RT-THREAD文档的图片


    image.png

    以上为理论,我们再实际用代码测试一下
    首先顺便打开一个工程,进行编译,得出区域使用情况

    Program Size: Code=112806 RO-data=13838 RW-data=1324 ZI-data=10396
    

    然后我们定义一个全局变量,并且为了防止被优化,调用打印来使用它

    char *data = "123456789";
    void pt_data()
    {
        rt_kprintf("%s",data);
    }
    //主函数中调用pt_data()
    

    再次编译得到新的区域使用情况

    Program Size: Code=112834 RO-data=13850 RW-data=1328 ZI-data=10392  
    

    接下里我们就对比一下,其中RO-data多了12个字节,来源于定义的字符串常亮"123456789",每个字符占8个字节,算上\0一共是10个字节,但是由于我们是32位单片机,只能是4字节的整数倍,所以这里使用了12个字节。
    再来是RW-data多了4个字节,原因是我们定义的char *data指针,同样因为是32位单片机,所以使用了4个字节。
    至于ZI-data少了4个字节,emmm这个我一脸懵逼,望大佬指教。


    接下来我们尝试定义一个未初始化的全局变量

    uint32_t a[100];
    void pt_data()
    {
        rt_kprintf("%d",a[0]);
    }
    //在主函数中调用pt_data
    

    然后得到新的区域使用情况

    Program Size: Code=112834 RO-data=13838 RW-data=1324 ZI-data=10796  
    

    我们能够发现,RO-data和RW-data均未改变,而ZI-data增加了400,正好就是数组a。

    相关文章

      网友评论

        本文标题:keil下的程序内存分布情况

        本文链接:https://www.haomeiwen.com/subject/ejilfctx.html