4

考虑以下CPU指令这需要存储器地址16777386(十进制),并将其存储在寄存器1:在编译时何时分配内存地址?

Move &0x010000AA, R1

传统节目被转换到组件(机器代码)。 (让我们忽略更复杂的现代系统,如jitting)。

但是,如果此地址分配在编译时静态完成,那么操作系统如何确保两个进程不使用相同的内存? (例如,如果你同时运行两次相同的编译程序)。

问:

如何,以及何时,并计划得到分配的内存地址?

虚拟内存:

我了解大部分(如果不是全部)现代系统使用存储器管理单元在硬件上允许使用的虚拟内存。地址空间的前几个八位字节用于引用哪个页面。如果每个进程使用不同的页面,这将允许内存保护。但是,如果这是如何执行内存保护的,那么原始问题仍然存在,只是这次是如何分配页码的?

EDIT

CPU:

一种可能性是CPU可以通过执行一个进程ID由OS执行基于存储器中的指令前分配处理存储器保护。但是,这只是推测,并且需要CPU架构在硬件方面的支持,这是我不确定RISC ISA会设计的。

回答

1

虚拟内存每个进程都有独立的地址空间,所以一个进程中的0x010000AA会引用与另一个进程中不同的值。

地址空间是由内核控制的page tables实现的,处理器用它来将虚拟页面地址转换为物理地址。使用相同地址页码的两个进程不是问题,因为进程具有单独的页表,并且映射的物理内存可能不同。

通常可执行代码和全局变量将被静态映射,堆栈将被映射到随机地址(某些漏洞更加困难),动态分配例程将使用系统调用来映射更多页面。

+0

其我的理解是,页面查找使用硬件以减少查找的时间成本(是内核接管页面错误,但应该是例外情况)。 MMU跟踪哪个进程正在运行?它如何知道一次将0x010000AA映射到物理地址X,但稍后将0x010000AA映射到物理地址Y? – James 2014-11-24 16:58:52

+0

@詹姆斯,处理器需要一个指向页表的寄存器(例如,x86 http://en.wikipedia.org/wiki/Control_register#CR3中的CR3)。 – zch 2014-11-24 17:16:14

0

(忽略Unix分支)进程内存的初始状态由可执行加载程序设置。链接器定义了初始内存状态,加载器创建它。该状态通常包括静态数据,可执行代码,可写入数据和堆栈的内存。

在大多数系统中,进程可以通过添加页面(也可能删除它们)来修改地址空间。

[忽略系统地址]在虚拟(逻辑)内存系统中,每个进程都有一个从零开始的地址空间(通常第一页未映射)。地址空间分为多页。操作系统将逻辑页面映射(并重新映射)为物理页面。

地址0x010000AA在一个进程中是每个进程中不同的物理内存地址。