寻求可区分-fPIC与非-fPIC编译目标文件的MWE
体现PIC与非PIC代码差异的最小示例
你的原示例无法体现差异,是因为函数仅包含本地算术运算,没有涉及全局变量、外部函数调用等需要寻址的操作——这类场景下PIC和非PIC生成的机器码完全一致。
要观察到差异,需要构造一个引用全局变量或调用外部函数的场景,以下是最小可行示例:
示例代码
// pic_demo.c int global_var = 42; int get_global() { return global_var; }
编译命令
- 编译非PIC目标文件:
gcc -c pic_demo.c -o pic_demo.o - 编译PIC目标文件:
gcc -c -fPIC pic_demo.c -o pic_demo_pic.o
查看差异
使用objdump -d命令反汇编两个目标文件,对比get_global函数的机器码:
非PIC版本反汇编片段
0000000000000000 <get_global>: 0: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # 6 <get_global+0x6> 2: R_X86_64_PC32 global_var-0x4 6: c3 retq
这里直接通过RIP相对寻址访问global_var,属于直接引用。
PIC版本反汇编片段
0000000000000000 <get_global>: 0: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 7 <get_global+0x7> 3: R_X86_64_REX_GOTPCRELX global_var-0x4 7: 8b 00 mov (%rax),%eax 9: c3 retq
PIC版本会先通过RIP相对寻址找到GOT(全局偏移表)中global_var的条目,再间接读取变量值——这是为了保证代码加载到任意内存地址时,都能正确定位全局变量,符合位置无关的要求。
内容的提问来源于stack exchange,提问作者MaPo
相关产品推荐
相关产品推荐

