打印
[开发工具]

为什么gcc编译出来的程序大小和Keil差别这么大

[复制链接]
9701|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pq113_6|  楼主 | 2017-6-13 13:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 pq113_6 于 2017-6-13 14:50 编辑

如题,STM32F103, 同一个项目,代码基本一样。
gcc编译出来(优化等级-O0)的:
Program Size:
      text           data            bss            dec            hex        filename
     31521           2512           8680          42713           a6d9        stm32f103.elf
keil编译出来(优化等级Level 0)的:
Program Size: Code=18630 RO-data=1554 RW-data=164 ZI-data=2180  
gcc使用CoIDE编译,是否有什么优化等级可以用?我试过-Os,结果程序跑不起来了。
沙发
grant_jx| | 2017-6-13 18:11 | 只看该作者
一个收钱的,一个免费的,你觉得呢?

使用特权

评论回复
板凳
john_lee| | 2017-6-14 00:13 | 只看该作者
1、-O0就是不优化,比较两者的Size没有意义。
2、还有-O1、-O2、-O3可用。
3、-Os跑不起来,99.99999999%是你的程序写法问题。静态分析不出来,就调试跟踪。

使用特权

评论回复
地板
pq113_6|  楼主 | 2017-6-14 13:25 | 只看该作者
本帖最后由 pq113_6 于 2017-6-14 13:58 编辑
john_lee 发表于 2017-6-14 00:13
1、-O0就是不优化,比较两者的Size没有意义。
2、还有-O1、-O2、-O3可用。
3、-Os跑不起来,99.99999999%是 ...

4种优化都试过,和Keil比还是差别比较大,程序确实是可能有问题的,这点还没有去查过,只是挺奇怪-O0或者keil是可以跑起来的。有2个程序,一个程序可以跑起来,keil编译出来只要15KB,gcc就算用-Os也要35KB,-O0是36KB,另一个程序keil编译出来大概30KB多,gcc只能用-Os,有63KB,单步debug都不行,用CoIDE debug没看到停下来。

使用特权

评论回复
5
pq113_6|  楼主 | 2017-6-14 14:01 | 只看该作者
grant_jx 发表于 2017-6-13 18:11
一个收钱的,一个免费的,你觉得呢?

只是讨论,其实用免费的也能用,memory不够可以上更大的。免费的用的人多了自然功能会越来越强大的。

使用特权

评论回复
6
john_lee| | 2017-6-14 16:53 | 只看该作者
本帖最后由 john_lee 于 2017-6-14 16:56 编辑

gcc 编译出来的代码 size 比 mdk 大,有很大一个原因是库的问题。arm gcc embedded 使用的 newlib 库,由于照顾了很多 C 的库标准,size 太大,不太适合单片机,而 mdk 的 microlib 库,是专门为单片机定制的,砍掉了库标准中的很多单片机开发上用不到的 feature。现在 gcc 也有了适合单片机的 newlib-nano 库,也是砍掉了很多 feature,你可以试一试。参考这篇**:Shrink Your MCU code size with GCC ARM Embedded 4.7

使用特权

评论回复
7
pq113_6|  楼主 | 2017-6-14 17:01 | 只看该作者
john_lee 发表于 2017-6-14 16:53
gcc 编译出来的代码 size 比 mdk 大,有很大一个原因是库的问题。arm gcc embedded 使用的 newlib 库,由于 ...

谢谢!我研究一下这篇**。另外,我看map文件里面有很多debug开头的东西,
.debug_info    0x00000000      0x2b2 ..\obj\stm32f0xx_crc.o
.debug_abbrev  0x00000000      0x16d ..\obj\stm32f0xx_crc.o
.debug_loc     0x00000000       0xc0 ..\obj\stm32f0xx_crc.o
.debug_aranges
                0x00000000       0x68 ..\obj\stm32f0xx_crc.o
.debug_ranges  0x00000000       0x58 ..\obj\stm32f0xx_crc.o
.debug_line    0x00000000      0x24c ..\obj\stm32f0xx_crc.o
.debug_str     0x00000000      0x2f0 ..\obj\stm32f0xx_crc.o
这个是不是多余的?

使用特权

评论回复
8
pq113_6|  楼主 | 2017-6-14 17:07 | 只看该作者
john_lee 发表于 2017-6-14 16:53
gcc 编译出来的代码 size 比 mdk 大,有很大一个原因是库的问题。arm gcc embedded 使用的 newlib 库,由于 ...

找到原因了,我用到了Printf的功能
void libPrintf(char *fmt,...)
{
        #if 0
        va_list ap;
        char string[256];
        va_start(ap,fmt);
        vsprintf(string,fmt,ap);
        uart1SendString(string);
        va_end(ap);
        #endif
}
把这个打印去掉后就编译size就差不多了
text           data            bss            dec            hex        filename
     17334             36            436          17806           458e        stm32f030.elf

使用特权

评论回复
9
john_lee| | 2017-6-14 17:49 | 只看该作者
.debug 是一些调试信息的段 (section),这些段会链接到目标文件(.elf)中,但它们的段标志为 0(不分配地址空间,不执行),并且这些段也不包含在程序头(program header)中,就不会写入hex以及单片机中,这些段就相当于文件附加的说明,它们的作用,就仅仅限于被调试程序读取并展现给你。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

284

帖子

2

粉丝