11

自从我在我的操作系统课上听说虚拟和物理内存概念的那一天起,这是一个非常基本的问题,令人难以置信。现在我知道在加载时和编译时,虚拟地址和逻辑地址绑定方案是相同的,但在执行时它们不同。

首先,为什么在编译和加载时生成虚拟地址是有益的,以及当我们应用 & 运算符获取变量地址、朴素数据类型、用户定义类型和函数定义地址时返回的内容是什么?

当它这样做时,操作系统如何准确地从虚拟地址映射到物理地址?这些问题是出于好奇,考虑到现代操作系统,我希望得到一些好的和深刻的见解,早期操作系统的情况如何。我只是 C/C++ 特定的,因为我对其他语言不太了解。

4

2 回答 2

4

在应用程序级别(例如 Linux 应用程序进程),仅存在虚拟地址。局部变量在堆栈上(或在寄存器中)。堆栈按调用框架组织。编译器在当前调用帧内生成局部变量的偏移量,通常是相对于堆栈指针或帧指针寄存器的偏移量(因此,局部变量的地址,例如在递归函数中,仅在运行时才知道)。

尝试在调试器中逐步执行递归函数gdb并显示一些局部变量的地址以了解更多信息。也试试bt.gdb

类型

cat /proc/self/maps

了解执行该命令的进程的地址空间(和虚拟内存映射)。cat

在内核中,从虚拟地址到物理 RAM 的映射是通过实现分页和驱动MMU的代码完成的。一些系统调用(尤其是mmap(2)和其他)可以更改进程的地址空间。

一些早期的计算机(例如 1950 年代或 1960 年代早期的计算机,如CAB 500IBM 1130IBM 1620)没有任何 MMU,甚至最初的Intel 8086也没有任何内存保护。那时(1960-s),C还不存在。在没有 MMU 的处理器上,您没有虚拟地址(只有物理地址,包括洗衣机制造商的嵌入式 C 代码)。有些机器可以通过物理开关保护对某些内存库的写入。今天,一些低端廉价处理器(洗衣机中的处理器)没有任何 MMU。大多数便宜的微控制器没有任何 MMU。通常(但并非总是),程序位于某些 ROM 中,因此不能被错误代码覆盖。

于 2013-03-27T08:24:15.047 回答
4

物理地址出现在硬件中,而不是软件中。操作系统内核中存在一个可能/偶然的异常。物理意味着它是系统总线和 RAM 芯片看到的地址。

物理地址不仅对软件无用,而且可能是一个安全问题。能够在没有地址转换的情况下访问任何物理内存,并且知道其他进程的地址,将允许不受限制地访问机器。

也就是说,较小的或嵌入式机器可能没有虚拟内存,并且一些较旧的操作系统确实允许共享库指定它们的最终物理内存位置。此类策略会损害安全性并且已过时。

于 2013-03-27T08:24:41.170 回答