3

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

char *p = malloc (10);

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

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

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

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

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

4

2 回答 2

3

我认为不同层次的混乱。

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

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

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

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


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

于 2012-04-13T04:53:47.270 回答
-1

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

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

于 2012-04-13T06:19:30.343 回答