作为更准确地了解 C 程序如何工作以及程序能够使用 libc 必须存在的最低内容级别的练习,我自己尝试主要使用 Gas 和 X86 汇编语言进行编程LD。
作为一个有趣的小挑战,我成功地组装并链接了几个链接到不同自制动态库的程序,但我无法从头开始编写程序以使用 libc 函数调用而不直接使用 gcc。
我了解各个 C 库函数的调用约定,并通过使用 objdump 和 readelf 彻底检查了 gcc 编译的程序,但还没有了解在 Gas 汇编文件中包含哪些信息以及哪些信息在 ld 中调用的参数以成功链接到 libc。有人对此有任何见解吗?
我在 x86 机器上运行 Linux。
最佳答案
要成功使用带有动态链接的 libc,至少需要做三件事:
- 链接
/usr/lib/crt1.o
,其中包含_start
,它将成为 ELF 二进制文件的入口点; - 链接
/usr/lib/crti.o
(在 libc 之前)和/usr/lib/crtn.o
(之后),它们提供了一些初始化和终止代码; - 告诉链接器二进制文件将使用动态链接器
/lib/ld-linux.so
。
例如:
$ cat hello.s
.text
.globl main
main:
push %ebp
mov %esp, %ebp
pushl $hw_str
call puts
add $4, %esp
xor %eax, %eax
leave
ret
.data
hw_str:
.asciz "Hello world!"
$ as -o hello.o hello.s
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o -lc hello.o /usr/lib/crtn.o
$ ./hello
Hello world!
$
关于assembly - 如何在不使用gcc的情况下将使用C标准库的气体汇编程序与ld链接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3577922/