assembly - 如何在不使用gcc的情况下将使用C标准库的气体汇编程序与ld链接?

标签 assembly ld gnu-assembler binutils

作为更准确地了解 C 程序如何工作以及程序能够使用 libc 必须存在的最低内容级别的练习,我自己尝试主要使用 Gas 和 X86 汇编语言进行编程LD。

作为一个有趣的小挑战,我成功地组装并链接了几个链接到不同自制动态库的程序,但我无法从头开始编写程序以使用 libc 函数调用而不直接使用 gcc。

我了解各个 C 库函数的调用约定,并通过使用 objdump 和 readelf 彻底检查了 gcc 编译的程序,但还没有了解在 Gas 汇编文件中包含哪些信息以及哪些信息在 ld 中调用的参数以成功链接到 libc。有人对此有任何见解吗?

我在 x86 机器上运行 Linux。

最佳答案

要成功使用带有动态链接的 libc,至少需要做三件事:

  1. 链接 /usr/lib/crt1.o,其中包含 _start,它将成为 ELF 二进制文件的入口点;
  2. 链接 /usr/lib/crti.o (在 libc 之前)和 /usr/lib/crtn.o (之后),它们提供了一些初始化和终止代码;
  3. 告诉链接器二进制文件将使用动态链接器 /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/

相关文章:

assembly - call *(%rax, %rcx,8) 在循环中是什么意思?为什么RAX和RCX之后要变?

gcc - 如何配置 gcc 默认使用 -no-pie?

gcc/ld - 使用 glibc.2.6 中的 __isoc99_sscanf@@GLIBC_2.7 符号创建一个新的 libc.so

linux - 我如何开始学习 asm(gas)?

assembly - 来自 AT&T 语法的 Intel Assembly ljmp 语法

optimization - 机器码对齐

assembly - C 编译器输出的此代码中的 MOVZX、CDQE 指令的含义/用途是什么?

c - 内联汇编导致没有前缀的错误

c - gcc 的原子操作和代码生成

caching - 为什么 Linux 在使用 GNU Linker 时不缓存对象和/或 ".so"文件?