为什么我的可执行文件在链接

时间:2016-08-26 18:08:49

标签: c arm embedded

我有一个小C程序,我需要在不同的芯片上运行。 可执行文件应小于32kb。 为此,我有几个工具链,包含不同的arm,mips等编译器。

该程序由几个文件组成,每个文件都编译为一个目标文件,然后链接到一个可执行文件。

当我使用系统gcc(x86)时,我的可执行文件大15kb。 使用arm工具链,可执行文件大65kb。 使用另一个工具链,它是47kb。

例如,对于arm,可执行文件中包含的所有对象都是14kb。

使用以下选项编译对象:

-march=armv7-m -mtune=cortex-m3 -mthumb -msoft-float -Os

对于链接,使用以下选项:

-s -specs=nosys.specs -march-armv7-m

nosys.specs库大274字节。

为什么我的代码只有14kb且库274字节时,我的可执行文件仍然大得多(65kb)?

更新

根据答案提出建议后,我从代码中删除了所有malloc和printf命令,并删除了未使用的包含。我还添加了编译标志-ffunction-sections -fdata-sections和链接标志--gc-sections,但可执行文件仍然太大。

为了进行实验,我创建了一个虚拟程序:

int main()
{
    return 1;
}

当我使用不同的编译器编译程序时,我得到了非常不同的可执行文件大小:

8.3 KB : gcc -Os
22 KB  : r2-gcc -Os
40 KB  : arm-gcc --specs=nosys.specs -Os
1.1 KB : avr-gcc -Os

那么为什么我的arm-gcc可执行文件要大得多呢? 我想,avr-gcc可执行文件也会进行静态链接。

2 个答案:

答案 0 :(得分:6)

您的x86可执行文件可能是动态链接的,因此您使用的任何标准库函数 - mallocprintf,字符串和数学函数等 - 都不包含在二进制文件中。

ARM可执行文件是静态链接的,因此这些函数必须包含在二进制文件中。这就是为什么它更大。要使其更小,您可能需要考虑使用-ffunction-sections -fdata-sections进行编译,然后与--gc-sections链接以丢弃二进制文件中任何未使用的函数或数据。

(" nosys.specs库"不是库。它是一个配置文件。真正的库文件在其他地方。)

答案 1 :(得分:0)

嵌入式软件移植取决于目标硬件和软件平台。 硬件平台分为mcu,cpus,可以运行linux操作系统。 软件平台包括编译器工具链和库。

比较mcu和x86硬件平台的程序映像大小毫无意义。 但是,使用不同的工具链来比较相同类型CPU上的程序图像大小是值得的。