静态编译 libc C 代码和 ASM 代码

标签 c gcc assembly ld

我有 ASM 代码:

    extern my_func
    extern printf
    extern exit
    global _start
section .data
    ...
section .text
  _start:
    ...
    call printf
    ...
    call my_func
    ...
    call exit

和C代码:

    int my_func(int a, int b)
    {
        return a+b;
    }

我在 64 位机器上使用 fedora。我希望可执行文件是 32 位的。 对于动态链接,我这样做:

nasm -f elf32 asm.asm ; this gives me asm.o
gcc -m32 -Wall -c c_code.c ; this gives me c_code.o
ld c_code.o asm.o -melf_i386 -L /usr/lib/ -lc -I /lib/ld-linux.so.2 ; this gives me a.out which runs fine and weights 5601 bytes.

我想做的是静态链接 libc。我执行以下操作:

gcc -o a2.out -m32 -static -m32 asm.o c_code.o

我得到错误:

asm.o: In function `_start':
asm.asm:(.text+0x0): multiple definition of `_start'
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o:(.text+0x0):
first defined here       
collect2: error: ld returned 1 exit status

然后我在 ASM 代码中将 _start 更改为 main,整个链接正常! ldd 显示“不是动态可执行文件”。但是创建的文件重量为 721067 字节!我认为它静态编译了很多不必要的代码。 所以,我的第一个问题是:

1) 如何为所需的 printf 和退出函数静态链接 libc?

当我尝试

gcc -m32 -o a3.out -lc asm.o c_code.o ; ASM file has main instead of _start

我得到一个重量为 7406 字节的文件。 ldd 显示与重量为 5601 字节的 a.out 相同的动态库。

2) 为什么会有这种差异?看起来像一些额外的代码在我的代码中“连接”_start 和 main ... 3)用gcc和ld链接有什么区别?

非常感谢您的关注!

最佳答案

1) How can I link statically only libc for the required printf and exit functions?

尝试使用 -nostartfiles -static -nostdlib -lc 进行编译,这将避免添加 crt1.o 和 crtend.o。但请记住,这将禁用所有 Glibc 初始化代码,因此某些 Glibc 函数将无法工作。

2) Why is that difference? Looks like some additional code that "connects" _start with main in my code...

GCC 添加了执行初始化的启动文件 (crt*.o)。有关详细信息,请参阅许多在线文章(例如 this one)。

3) What is the difference between linking with gcc and ld?

上面已经回答了,但通常您可以运行 gcc -v 并检查 ld(或 collect2)的参数。

关于静态编译 libc C 代码和 ASM 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41564885/

相关文章:

linux - GCC版本是4.8,在centos中仍然出现unrecognized command -std=c++11的错误

c++ - 奇怪的 C++ 链接错误

assembly - 如何在汇编语言编程中提示用户输入字符串并再次显示

documentation - 我如何在流程图中表示中断(对于微 Controller )?

c - zdelta 压缩库段错误

c - 使用常量文件指针倒带和 fscanf

c++ - C中浮点运算错误

c - 创建链表头的问题

c - 在不同的 C 文件中使用函数

assembly - 在 Motorola 68000 Assembly 中如何将奇数变成偶数,反之亦然?