考虑以下CPU指令,该指令占用地址16777386(十进制)的存储器并将其存储在寄存器1中:
Move &0x010000AA, R1
传统上,程序在编译时被转换为程序集(机器代码)。 (让我们忽略更复杂的现代系统,如jitting)。
但是,如果在编译时静态完成此地址分配,操作系统如何确保两个进程不使用相同的内存? (例如,如果你同时运行两次相同的编译程序)。
问题:
程序如何以及何时分配内存地址?
虚拟记忆:
我理解大多数(如果不是全部)现代系统在硬件中使用内存管理单元以允许使用虚拟内存。地址空间的前几个八位字节用于引用哪个页面。如果每个进程使用不同的页面,这将允许内存保护。但是,如果这是强制执行内存保护的方式,原始问题仍然存在,只是这次是如何分配页码?
修改:
CPU:
一种可能性是CPU可以通过在执行基于内存的指令之前强制执行OS分配进程ID来处理内存保护。然而,这只是推测,并且需要CPU架构支持硬件,我不确定RISC ISA是否会被设计用。
答案 0 :(得分:1)
对于虚拟内存,每个进程都有单独的地址空间,因此一个进程中的0x010000AA将引用与另一个进程中不同的值。
地址空间由内核控制的page tables实现,处理器使用它来将虚拟页面地址转换为物理页面地址。使用相同地址页码的两个进程不是问题,因为进程具有单独的页表,并且映射的物理内存可能不同。
通常可执行代码和全局变量将被静态映射,堆栈将被映射到随机地址(某些漏洞利用更难),动态分配例程将使用系统调用来映射更多页面。
答案 1 :(得分:0)
(忽略Unix分支)进程内存的初始状态由可执行加载程序设置。链接器定义初始内存状态,加载器创建它。该状态通常包括内存到静态数据,可执行代码,可写数据和堆栈。
在大多数系统中,进程可以通过添加页面来修改地址空间(也可以删除它们)。
[忽略系统地址]在虚拟(逻辑)内存系统中,每个进程都有一个从零开始的地址空间(通常不会映射第一页)。地址空间分为页面。操作系统将逻辑页映射(并重映射)到物理页。
一个进程中的地址0x010000AA就是每个进程中的差异物理内存地址。