我已阅读主题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.cpp 并作为 g ++ -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进行编译时, jump 和 je 命令的参数地址与位置无关。所以两个objdumps应该是不同的。我理解错了什么?
答案 0 :(得分:2)
-fPIC
在较新的gcc
版本中处于启用状态。即使没有选项,代码也与位置无关:
eb 07 jmp 1c <_Z3fooi+0x1c>
这与位置无关,查看2字节操作码,即使反汇编打印符号及其偏移量也是为了清晰。
请注意,无论选项如何,编译器很可能会为那种短跳产生与位置无关的代码。
所以这个标志现在不是很有用。但您可以使用-fno-PIC
开关禁用PIC。
答案 1 :(得分:2)
GCC编译器无法有意生成与位置相关的代码。这种能力没有任何实际意义。
GCC可以做的事实上是生成与位置无关的代码(使用-fPIC
选项),或者&#34;无论什么&#34;代码(没有-fPIC
选项)。当你使用&#34;无论什么&#34;模式,编译器只是忽略了位置依赖性的问题,并根据其他考虑因素来决定代码生成。这意味着,即使您没有请求-fPIC
,您仍然可能很容易地完全依赖与位置无关的代码&#34;意外&#34;:因为恰好与位置无关的代码最适合其他原因(更紧凑,运行更快等)。
如果您想观察差异,则需要一个更具代表性的示例。在你的例子中,所有跳跃都接近跳跃。它们通过相对(基于偏移的)跳转指令自然地实现。任何敏感的编译器都会在这种情况下使用这种相对跳转。这样做的副作用是,即使您没有明确要求,也最终会得到与位置无关的代码。位置独立来自免费&#34;在这种情况下。
如果你想观察差异,你需要一个不会出现位置独立的例子#34;免费&#34;。你需要一些能够在位置独立性和其他重要因素(如效率和/或规模)之间进行明确权衡的事情。如果你想出这样一个例子,你会看到-fPIC
所产生的差异。