objdump 显示的地址是最终地址还是偏移量?

Are the addresses displayed by objdump final addresses or just offsets?

假定此 C 代码,使用 gcc file.c:

编译
int main(){
 return 0;
}

使用 objdump 生成的输出:

0000000000000660 <main>:
660:    55                      push   %rbp
661:    48 89 e5                mov    %rsp,%rbp
664:    b8 00 00 00 00          mov    [=11=]x0,%eax
669:    5d                      pop    %rbp
66a:    c3                      retq   
66b:    0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

注意第一个地址是660

这是来自 GDB 的相同输出:

0x555555554660 <main>                   push   %rbp
0x555555554661 <main+1>                 mov    %rsp,%rbp
0x555555554664 <main+4>                 mov    [=12=]x0,%eax
0x555555554669 <main+9>                 pop    %rbp
0x55555555466a <main+10>                retq

注意每个地址左侧添加的 5s

这是我的问题:

1- 左边的5s是什么?为什么 objdump 没有它们?

2- 这些只是偏移量吗?或者在二进制文件中硬编码的最终地址将被加载到虚拟内存中。

3- 如果这些是偏移量,那么常规可执行文件和 PIE 之间有什么区别?我认为只有 PIE 代码是位置独立的,并且在加载期间分配了随机地址,我没有使用 -fpie 选项进行编译。我也用过 -fno-pie 并没有什么区别。

1- What are the 5s on the left? why doesn't objdump have them?

555…55516 是 1000…00016 的三分之一。你看到多个五只是因为有人将某个特定的内存区域分成三块。 objdump 没有它们,因为它只是显示偏移量。

2- Are these just offsets? or final addresses hard coded in the binary which will be loaded in virtual memory.

它们是相对于它们所在程序部分开始的偏移量。

3- If these are offsets than what is the difference between a regular executable and PIE? I thought only PIE code is position independent and has random addresses assigned to it during load time, I didn't compile with -fpie option. I have also used -fno-pie and it made no difference.

位置无关的可执行文件在程序执行期间计算其地址。它使用基址寄存器或提供给它的其他信息来定位事物,或者它使用相对于程序计数器的地址,或独立于程序位置的其他寻址形式。

相反,不依赖于位置的程序可以使用绝对形式的寻址。但是,绝对地址不一定内置到目标模块中。目标模块中的地址可能仍然是相对于程序部分或其他参考点的偏移量。加载程序时,加载程序选择将程序段放在何处,并调整指令中内置的所有地址,将它们从偏移地址更改为绝对地址。目标模块和最终的可执行文件包含描述所有需要这些“修正”的位置的数据结构。

位置无关代码可以同时在两个不同进程的两个不同虚拟内存地址使用。因为它使用相对寻址形式构造所有地址,所以代码的位置无关紧要。使用加载程序固定地址的代码与特定地址相关联;加载程序完成后,代码在其指令中嵌入了特定地址,因此无法将其移动到其他位置。