当我使用
%p
打印变量的地址时,我得到一个非常大的 12 位十六进制值。然而,当我使用 objdump
查看可执行文件的实际布局时,该变量位于一个小得多的 4 位十六进制值。这是为什么?
我很确定较大的地址不是变量的物理地址,因为它在用户空间中运行,并且绝对不应该访问物理地址。我还为此禁用了 ASLR,因此大地址不仅仅是随机化的产物。
#include <unistd.h>
#include <stdio.h>
static int testInt = 5;
int main() {
printf("address of testInt: %p\n", (void*)&testInt);
return 0;
}
当我运行它时,它会打印 testInt 的地址
0x555555558010
。然而,根据objdump
,testInt位于字节0000000000004010
。
操作系统加载器的功能是在运行时定位整个代码,可执行文件中的“地址”是距最终运行时位置的偏移量,而不是绝对地址。
现代操作系统将加载到虚拟地址并使用地址空间布局随机化(ASLR)作为针对某些类型攻击的安全措施 - 因此在执行之间它甚至可能不是相同的地址。