c - 使用 gcc 编译时 -ffreestanding 和 -nostdlib 之间的区别

标签 c gcc compilation x86 linker

我正在使用带有 x84-elf64-gcc 编译器的 64 位 linux 机器。我刚刚开始低级编程,想了解 C 代码实际上是如何翻译成二进制的。这主要用于操作系统开发,因为我知道处理器不理解 ELF 或任何其他格式,并且只理解二进制。

例如下面的c文件:

//test.c
int func()
{
    return 0x12345678;
}

当我用 gcc 编译时:

gcc test.c

我收到以下错误:

(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status

所以我猜测链接器有问题。 我这样做:

gcc test.c -c 

我得到了一个 ELF 目标文件,我做了一个 objdump 并得到了预期的结果:

0000000000000000 <func>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   b8 78 56 34 12          mov    $0x12345678,%eax
   9:   5d                      pop    %rbp
   a:   c3                      retq   

但是当我使用 -m32 选项和 objdump“交叉编译”一个 32 位版本时,我得到:

hello.o:     file format elf32-i386


Disassembly of section .text:

00000000 <func>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   e8 fc ff ff ff          call   4 <func+0x4>
   8:   05 01 00 00 00          add    $0x1,%eax
   d:   b8 78 56 34 12          mov    $0x12345678,%eax
  12:   5d                      pop    %ebp
  13:   c3                      ret    

Disassembly of section .text.__x86.get_pc_thunk.ax:

00000000 <__x86.get_pc_thunk.ax>:
   0:   8b 04 24                mov    (%esp),%eax
   3:   c3                      ret    

我在之前的回答中读到这与位置无关代码有关:undefined reference to `_GLOBAL_OFFSET_TABLE_' in gcc 32-bit code for a trivial function, freestanding OS

为什么用-m32选项编译会有这样的变化? 而且,我被建议在编译时使用-ffreestanding 选项,但它在这里似乎没有效果。我读过 -ffreestanding 告诉编译器没有标准库,那么 -nostdlib 是什么?

注意:我对这种硬核 c 编程还比较陌生,我认为这里的主要问题是我并不真正了解链接器/编译器的工作原理。 :(

最佳答案

选项控制过程的两个部分:

  • -freestanding向编译器表明它应该是一个独立的,AFAIK 唯一的影响是禁用一些内置函数,如 memcpy;

  • -nostdlib表示默认情况下不应链接任何库和启动文件。

关于c - 使用 gcc 编译时 -ffreestanding 和 -nostdlib 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59612257/

相关文章:

c - 绕过 "cast increases required alignment order"消息

c++ - 如何将类方法的地址转换为 (void *)

收集 2 : error: ld returned 1 exit status, gcc

C++ - 方法/成员访问

c++ - 用.txt文件编译多个C++文件?

c - 如何使用 TOS 设置消息优先级?

c - 这是经典书籍Linux Device Drivers的错误吗?

c - 具体模乘算法

c - 如何在 C 中抑制 "unused parameter"警告?

c++ - GCC - 包含编译标志的宏