就机器代码而言,链接静态库.a文件与链接.o对象文件集合有什么区别?

问题描述 投票:0回答:1
  1. 两种情况下的汇编指令是否相同?或者可执行文件完全不同?

  2. 可能会影响执行性能吗?

  3. 链接库是否会产生一些指令加载开销? (因为可执行文件更大)

我正在开发一个嵌入式 C 项目,我们从 RAM 缓存区域运行部分代码。当我们尝试将这部分代码捆绑为链接器中的库时,我们发现执行性能有所下降。我试图理解为什么会发生这种事。

assembly gcc linker embedded machine-code
1个回答
0
投票

静态库只是包含目标文件的存档。汇编指令是相同的。区别在于哪些目标文件链接到可执行文件。

链接目标文件集合时,所有目标文件都链接为可执行文件。 与静态库链接时,仅链接库中所需的目标文件。

例如有目标文件:

foo.o
包含两个符号:
foo1
foo2
:

$ nm foo.o 
0000000000000000 T foo1
0000000000000010 T foo2

bar.o
包含两个符号:
bar1
bar2
:

$ nm bar.o
0000000000000000 T bar1
0000000000000010 T bar2

main.o
参考
foo1

$ nm main.o 
                 U foo1
0000000000000000 T main

main.o
foo.o
bar.o
链接在一起会生成包含所有四个符号的可执行文件:

$ gcc -o main-obj main.o foo.o bar.o
$
$ nm main-obj | grep ' T '
0000000000001160 T bar1
0000000000001170 T bar2
0000000000001174 T _fini
0000000000001140 T foo1
0000000000001150 T foo2
0000000000001000 T _init
0000000000001020 T main
0000000000001040 T _start

foo.o
bar.o
放入库并与其链接会生成仅包含
foo.o
中的符号的可执行文件:

$ ar rcs lib.a foo.o bar.o
$ gcc -o main-lib main.o lib.a
$
$ nm main-lib | grep ' T '
0000000000001154 T _fini
0000000000001140 T foo1
0000000000001150 T foo2
0000000000001000 T _init
0000000000001020 T main
0000000000001040 T _start

因此,就可执行文件大小而言,使用默认标志链接目标文件集合并不是最佳选择。 但是,使用链接时优化 (

-flto
) 和/或链接器垃圾收集 (
-fdata-sections
-ffunction-sections
-Wl,--gc-sections
) 可能会消除这种差异,但代价是增加目标文件的大小。

© www.soinside.com 2019 - 2024. All rights reserved.