理解虚拟地址和虚拟地址空间

15

我读到这样一段话:"当程序执行像:MOV REG,1000这样的指令时,它是将内存地址1000的内容复制到REG中。地址可以使用索引、基地址寄存器、段寄存器和其他方式来生成。

这些程序生成的地址被称为虚拟地址,并形成了虚拟地址空间。"

请问有人能解释一下,(这些程序生成的地址被称为虚拟地址)是什么意思吗?

2个回答

39
程序和数据以数字形式存储在内存单元中。每个内存单元都有一个唯一的数字,称为其地址。表示有效地址的数字范围称为地址空间。
当程序运行时,CPU从内存中读取数据并将结果写回内存。CPU通过指定读取或写入操作所针对的内存单元的地址来与内存通信。
CPU可以以多种方式生成地址(记住,地址只是一个数字)。表示地址的数字可以在寄存器中,也可以存储在另一个内存位置,可以通过将偏移量加减到寄存器中来计算等等。在所有情况下,编译后的程序指示CPU如何生成所需读取或写入的地址。
现代体系结构允许多个程序执行,就好像它们拥有整个逻辑地址空间一样。换句话说,几个程序可以在相同的地址处写入内存位置,而不会覆盖彼此的结果。这是通过虚拟化地址空间实现的:假设A和B程序生成了一个写入0x1000内存位置的操作。 CPU在操作系统的帮助下,可以对地址进行其他调整,并将其映射到程序A的物理地址0x60001000和程序B的物理地址0x5F001000。两个程序都认为自己写入了0x1000位置,因为它们在虚拟地址空间中操作。它们的内存模型是一个连续块,从0开始,一直延续到0x000100000000(假设您的系统为进程提供了4GiB的可用内存)。但是,这种模型之所以有效,是因为CPU还会将它们的逻辑地址转换为物理地址,在运行程序的过程中根据需要分配和回收。
由于表示地址的相同数字对于程序和CPU来说具有不同的含义,程序的地址空间称为虚拟地址空间,而CPU的地址空间称为物理地址空间。

4
当然是虚拟的:对于程序而言,它只是0x1000。在我的例子中,虚拟0x1000单元的物理(硬件)地址为程序A的0x60001000,而程序B为0x5F001000。你的程序认为它正在写入0x1000,但硬件实际上写入了一个完全不同的地址。 - Sergey Kalinichenko
@dasblinkenlight 抱歉有点晚了。我理解你的意思,但是使用虚拟地址空间的实用性是什么呢?为什么程序A不能直接说“写入0x60001000”,程序B不能直接说“写入0x5F001000”呢? - HelloWorld123456789
1
@RikayanBandyopadhyay 因为0x600010000x5F001000地址是由操作系统在加载可执行文件时确定的,而不是可以编译到程序中的内容。 - Sergey Kalinichenko
但是这些地址难道不是可重定位的,并且在执行之前由加载器进行了调整吗? - HelloWorld123456789
在没有虚拟内存支持的系统上,是的。此外,并非所有地址都可以由加载程序进行校正 - 例如,在动态计算地址的情况下,加载程序可能无法看到数据操作以识别结果将用作地址的事实。 - Sergey Kalinichenko
显示剩余7条评论

1
当程序访问内存时,它并不知道也不关心支持地址的物理内存存储在哪里。它知道操作系统和硬件需要共同工作来映射定位正确的物理地址,从而提供对所需数据的访问。因此,我们称程序用于访问内存的地址为虚拟地址。虚拟地址由两部分组成:页和该页中的偏移量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接