我有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和exit函数静态链接libc?
当我尝试
时gcc -m32 -o a3.out -lc asm.o c_code.o ; ASM file has main instead of _start
我得到一个权重7406字节的文件。 ldd显示与a.out相同的动态库,权重为5601字节。
2)为什么会有这种差异?看起来像我的代码中“连接”_start与main的一些额外代码...... 3)链接gcc和ld有什么区别?
非常感谢您的关注!
答案 0 :(得分:0)
1)如何仅为所需的printf静态链接libc 和退出功能?
尝试使用-nostartfiles -static -nostdlib -lc
进行编译,这将避免添加crt1.o和crtend.o。但请记住,这将禁用所有Glibc初始化代码,因此某些Glibc函数将无法工作。
2)为什么会有这种差异?看起来像一些额外的代码 "连接" _start with main in my code ...
GCC添加执行初始化的启动文件(crt*.o
)。有关详细信息,请参阅许多在线文章(例如this one)。
3)使用gcc和ld链接有什么区别?
上面已经回答过,但一般情况下你可以运行gcc -v
并检查ld(或者收集2)的论点。