【问题标题】:Dereferencing a pointer at lower level in C在 C 中取消引用较低级别的指针
【发布时间】:2012-04-12 22:24:31
【问题描述】:

当malloc返回一个指针(一个数据块的虚拟地址)时,

char *p = malloc (10);

p 有一个虚拟地址,(比如 x)。而p 拥有一个由 10 个地址组成的块的虚拟地址。 假设这些虚拟地址是从 y 到 y+10。

这10个地址属于一个页,虚拟-->物理映射放在页表中。

当处理器取消引用指针 p 时,比如 printf("%c", *p); ,处理器如何知道它必须访问 y 处的地址?

是否为了取消引用指针而访问了两次页表,换句话说 - 打印 p 指向的地址?具体是怎么做的,谁能解释一下?

另外,为了访问堆栈变量,处理器是否必须通过页表访问它? 堆栈指针寄存器(SP)不是已经不指向堆栈了吗?

【问题讨论】:

  • 你明白 malloc 没有被定义为返回一个“虚拟地址”(即它是特定于实现的)?.
  • 假设我们在这种情况下假设它返回虚拟地址?但是,我知道它返回一个指针(堆中内存块的地址)。返回的地址可以是物理的/虚拟的。无论如何,现在我的问题是,如果返回的地址是虚拟的,处理器是否必须第二次访问页表才能访问堆中的数据。
  • 错字:这 10 个对象位于 yy+9。允许指针指向y+10(即十个对象之后的位置),但不允许取消引用它。

标签: c pointers memory-management


【解决方案1】:

我认为不同的层次混淆了。

首先,页表:这是一种数据结构,它使用一些内存来提供指向更多内存的指针。给定一个特定的虚拟地址,它可以将其解构为表中的索引。目前,这正在内核中进行,但可以在用户空间中实现相同的想法。

现在,下一步是流程。每个进程都有自己的内存视图,因此有自己的一组页表。处理器如何知道这些不同的页表位于何处?在一个名为 cr3 的特殊控制寄存器中。更改进程有时称为上下文切换。这是正确的,因为设置 cr3 会改变虚拟内存的进程视图。

但下一个问题是,处理器是如何理解虚拟内存的概念的呢?好吧,在一些较旧的架构中(想到 MIP),系统会保留最近转换的内存的缓存,并为如何处理虚拟内存访问提供指导。在 x86 中,缓存(通常称为翻译后备缓冲区)实际上是在硬件中实现的。处理器存储这些翻译,以便它可以自动处理页表查找。如果有缓存未命中,那么它实际上会遍历操作系统设置的页表结构来查找它应该引用的内容。

当然,这意味着处理器必须至少有两种不同的模式:一种假设地址是直接的,另一种是遍历页表。第一种模式,真实模式,在引导时存在,并且只有在引导加载程序打开虚拟模式并跳转到其余部分的开头之前足够长的时间来设置表格的代码。


对我的冗长解释的简短回答是,很可能根本不会访问页表,因为处理器已经进行了地址转换。

【讨论】:

    【解决方案2】:

    而 p 持有一个由 10 个地址组成的块的虚拟地址。

    你很困惑。 p 是一个指针,保存一个 10 字节块的地址;如何解释这些字节取决于应用程序。

    【讨论】:

    • 学究式地说,发帖人是正确的,有 10 个地址。 (不能保证块中的地址不超过 10 个,但 C 标准保证有 至少 10 个地址,而且我知道没有一个平台不正好有 10 个.)
    • 我将他的句子和示例解释为p[0]==y, p[1]==y+1 其中y 是一些指针值。
    猜你喜欢
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2020-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多