当malloc返回指针(数据块的虚拟地址)时,
char *p = malloc (10);
p有一个虚拟地址,(比如x)。 p
保存10个地址块的虚拟地址。
假设这些虚拟地址是从y到y + 10.
这10个地址属于一个页面,而虚拟 - >物理映射放在页表中。
当处理器取消引用指针p时,例如printf("%c", *p);
,处理器如何知道它必须访问y
处的地址?
页面表是否被访问了两次才能取消引用指针,换句话说 - 打印p
指向的地址?究竟是怎么做的,任何人都可以解释一下吗?
另外,为了访问堆栈变量,处理器是否必须通过页表访问它? 堆栈指针寄存器(SP)是不是已经指向堆栈了?
答案 0 :(得分:3)
我认为不同层次的混乱。
首先, 页表 :这是一种使用一些内存来提供指向更多内存的指针的数据结构。给定一个特定的虚拟地址,它可以将其解构为表中的索引。现在,这发生在内核的封面下,但是可以在用户空间中实现同样的想法。
现在,下一步是 进程 。每个进程都有自己的内存视图,因此有一组页表。处理器如何知道这些不同的页表所在的位置?在一个名为 cr3 的特殊控制寄存器中。更改过程有时称为上下文切换;这是正确的,因为设置cr3会改变虚拟内存的进程视图。
但接下来的问题是,处理器如何理解虚拟内存的概念?好吧,在一些较旧的架构中(MIP想到),系统会保留最近翻译的内存缓存,并为如何处理虚拟内存访问提供指导。在x86中,缓存(通常称为转换后备缓冲区)实际上是在硬件中实现的。处理器存储这些转换,以便它可以自动处理页表查找。如果有一个缓存未命中,那么它实际上将遍历操作系统设置的页表结构,以查找它应该引用的内容。
当然,这意味着处理器必须至少有两种不同的模式:一种假定地址是直接的,另一种是遍历页面表。第一种模式实模式,在启动时只有很长时间才能在引导加载程序打开虚拟模式之前设置表并跳转到其余模式的开头代码。
我长期解释的简短回答是,很可能根本不会访问页表,因为处理器已经有地址转换。
答案 1 :(得分:-1)
你很困惑。p保存10个地址块的虚拟地址。
p
是一个保存10字节块地址的指针;如何解释这些字节取决于应用程序。