2

我已阅读主题GCC -fPIC option

所以我创建了我的 testlib.cpp。

int foo(int num)
{   
    int result;

    if (num != 0)
    {
        result = 1;
    }
    else
    {
        result = 2;
    }

    return result;
}

当我编译为 g++ -c -o testlib.o testlib.cppg++ -fPIC -c -o testlib.o testlib.cpp 时,testlib.o 的相应 objdump 是相同的:

objdump -d testlib.o -M intel

testlib.o:     file format elf32-i386

Disassembly of section .text:

00000000 <_Z3fooi>:
   0:   55                      push   ebp
   1:   89 e5                   mov    ebp,esp
   3:   83 ec 10                sub    esp,0x10
   6:   83 7d 08 00             cmp    DWORD PTR [ebp+0x8],0x0
   a:   74 09                   je     15 <_Z3fooi+0x15>
   c:   c7 45 fc 01 00 00 00    mov    DWORD PTR [ebp-0x4],0x1
  13:   eb 07                   jmp    1c <_Z3fooi+0x1c>
  15:   c7 45 fc 02 00 00 00    mov    DWORD PTR [ebp-0x4],0x2
  1c:   8b 45 fc                mov    eax,DWORD PTR [ebp-0x4]
  1f:   c9                      leave  
  20:   c3                      ret   

而且我希望在使用 -fPIC 编译时,跳转je命令的参数地址与位置无关。所以这两个objdumps应该是不同的。我理解错了什么?

4

2 回答 2

2

-fPIC在较新gcc版本中默认启用。即使没有选项,代码也是位置无关的:

eb 07                   jmp    1c <_Z3fooi+0x1c>

这是与位置无关的,查看 2 字节操作码,即使反汇编打印符号及其偏移量也是如此。

请注意,无论选项如何,编译器很可能会为这种短跳转生成与位置无关的代码。

所以这个标志现在不是很有用。-fno-PIC但是您可以使用开关禁用 PIC 。

于 2016-12-24T09:19:23.153 回答
2

GCC 编译器没有能力故意生成与位置相关的代码。这种能力没有任何实际意义。

GCC 可以做的实际上是生成与位置无关的代码(带-fPIC选项)或“随便”代码(不带-fPIC选项)。当您使用“whatever”模式时,编译器会简单地忽略位置依赖性问题,并将其关于代码生成的决定基于其他考虑因素。这意味着即使您没有请求-fPIC,您仍然可能很容易地“意外”地得到与位置无关的代码:因为碰巧位置无关的代码由于其他原因而工作得最好(更紧凑,运行速度更快等) .)

如果要观察差异,则需要一个更具代表性的示例。在您的示例中,所有跳跃都接近跳跃。它们自然是通过相对(基于偏移的)跳转指令实现的。任何明智的编译器都会在这种情况下使用这种相对跳转。这样做的副作用是,即使您没有明确请求,您最终也会得到与位置无关的代码。在这种情况下,位置无关性是“免费的”。

如果您想观察差异,您需要一个位置无关性不会“免费”出现的示例。您需要在位置独立性和其他重要因素(如效率和/或规模)之间进行明确权衡的东西。如果你想出这样一个例子,你会看到不同之处-fPIC

于 2016-12-24T09:44:21.683 回答