gpt4 book ai didi

c - 如何避免 C 运行时 (crt*.o) 垃圾

转载 作者:太空狗 更新时间:2023-10-29 16:01:02 25 4
gpt4 key购买 nike

我有两个C源文件

foo1.c:

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
puts("hello world");
return 0;
}

foo2.c:

#include <stdlib.h>
#include <stdio.h>

void _start(void)
{
puts("hello world");
exit(0);
}

然后我在我的 i386 GNU/Linux 平台上像这样编译它们:

$ #compile foo1
$ cc -o foo1 foo1.c
$ #compile foo2
$ cc -S foo2.c
$ as -o foo2.o foo2.s
$ ld -o foo2 -dynamic-linker /lib/i386-linux-gnu/ld-linux.so.2 -lc foo2.o
$ #notice that crt1.o and others are missing

从用户的角度来看,输出的可执行文件做同样的事情。

$ ./foo1
hello world
$ ./foo2
hello world

但它们是不同的:

$ wc -c foo1
5000
$ wc -c foo2
2208
$ objdump -d foo1 | wc -l
238
$ objdump -d foo2 | wc -l
35

即使我启用 gcc 的 -Os 选项来优化大小,

$ #compile foo1
$ gcc -o foo1 foo1.c -Os

它并没有小很多:

$ wc -c foo1
4908
$ objdump -d foo1 | wc -l
229

有没有办法让 GCC 优化 crt1.o 的部分和我怀疑导致文件大小过大的 friend ,而不求助于非标准代码和奇怪的代码(在某些情况下可能有害) )编译?我的 GCC 版本字符串是“gcc (Debian 4.9.2-10) 4.9.2”。

最佳答案

对于 gcc/clang,您可以使用 -nostartfiles,但是您使用的 c 库可能依赖于它自己的 _start() 动态链接实现。由于您使用的是 Linux,我建议您使用 musl-libc 的静态构建。

或者,您可以只实现 write()exit() 系统调用,并将 '\n' 添加到您的字符串中,通过使用 _start() 而不是 main()。如果您需要访问 argc、argv 和 envp,您将需要一些内联汇编来访问堆栈(无论架构如何,Linux 都会将这些传递到所有 ELF 二进制文件的堆栈上)。

关于c - 如何避免 C 运行时 (crt*.o) 垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38860373/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com