【问题标题】:What is inside a pointer on a modern x64 system?现代 x64 系统上的指针内部是什么?
【发布时间】:2021-08-16 04:54:02
【问题描述】:

此代码示例:

int x = 75;
int *p = &x;

printf("%llx\n",p);

写入一个 64 位数字。我要问的是,这个数字到底是多少?是的,它是一个地址。

但它是存储值 75 的虚拟内存中的绝对地址吗?或者它可能从某个页面标记偏移,或者从程序内存块的“起点”偏移?

如果重要的话,我要问的是典型 x64 英特尔芯片上的 64 位 Windows 10。

【问题讨论】:

    标签: c windows 64-bit


    【解决方案1】:

    是的,它是你程序virtual address space中的绝对地址。

    这不是偏移量。

    在 16 位 Windows(30 年前很常见)中,使用了 segmented memory model,其中指针被分段,由 16 位段指针和 16 位偏移量组成(共 32 位) .

    但是,32 位和 64 位 Windows 都使用flat memory model,它使用绝对地址。

    【讨论】:

    • 你说的是“你的程序的虚拟地址空间”。这是否意味着另一个程序中的相同 64 位可以指向物理内存中的另一个地址?还是它对特定的物理位置是全球唯一的?
    • @CaptainCodeman 实际上可以保证另一个程序中相同的 64 位指向物理内存中的另一个地址(如果它指向任何东西)。
    • 那么 ReadProcessMemory 是如何工作的呢?你给它一个虚拟地址;这是否意味着它基于目标进程的地址空间?
    • @WillihamTotland:原则上,您是正确的。但是,某些系统 DLL,例如 kernel32.dll,总是映射到每个进程中的相同虚拟地址。此外,不能保证每个虚拟地址都映射到物理地址。即使是有效的虚拟地址也不一定映射到物理地址。例如,虚拟地址的内容可以是paged到磁盘,这样它甚至不存在于内存中。
    • @CaptainCodeman:是的,在调用ReadProcessMemory时,还必须指定目标进程。您传递给该函数的地址适用于目标进程的虚拟地址空间。
    【解决方案2】:

    它是一个虚拟地址,它是一个虚拟页码和一个从页面开始的偏移量。翻译机制在进程的页表中查找相应的物理页码,并结合偏移量得出物理地址。

    【讨论】:

    • 是的,你是对的,在将虚拟地址转换为物理地址时,使用了页表,为了进行这种转换,虚拟内存地址分为两部分:1. 索引页表和 2. 页偏移量。但是,只有操作系统(维护页表)必须了解此技术细节。对于普通程序员来说,这无关紧要(除非您正在编写内核驱动程序)。普通程序员通常只会看到并关心进程的平面虚拟地址空间。
    猜你喜欢
    • 2015-03-19
    • 1970-01-01
    • 2014-08-24
    • 2016-02-04
    • 2021-04-06
    • 1970-01-01
    • 2011-05-19
    • 2011-02-13
    相关资源
    最近更新 更多