两种情况下的汇编指令是否相同?或者可执行文件完全不同?
可能会影响执行性能吗?
链接库是否会产生一些指令加载开销? (因为可执行文件更大)
我正在开发一个嵌入式 C 项目,我们从 RAM 缓存区域运行部分代码。当我们尝试将这部分代码捆绑为链接器中的库时,我们发现执行性能有所下降。我试图理解为什么会发生这种事。
静态库只是包含目标文件的存档。汇编指令是相同的。区别在于哪些目标文件链接到可执行文件。
链接目标文件集合时,所有目标文件都链接为可执行文件。 与静态库链接时,仅链接库中所需的目标文件。
例如有目标文件:
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
) 可能会消除这种差异,但代价是增加目标文件的大小。