逻辑地址的真正用途是什么?

What is the real use of logical addresses?

这是我对逻辑地址的理解:

使用逻辑地址是为了防止物理内存上的数据被破坏。通过使用逻辑地址,进程将无法直接访问物理内存,从而确保它不能在已访问的物理内存位置存储数据,从而保护数据完整性。 我怀疑是否真的有必要使用逻辑地址。物理内存上数据的完整性可以通过使用不允许进程访问或修改已被其他进程访问的内存位置的算法等来保存。

它被 OS 模拟为程序,就好像它们在使用物理内存一样。出于数据完整性的目的,需要额外的层(逻辑地址)。您可以将逻辑地址类比为地址的OS语言,因为如果没有这个映射,OS将无法理解什么是"actual" 允许任何程序使用的地址。为了消除这种歧义,需要逻辑地址映射,以便 OS 知道什么逻辑地址映射到什么物理寻址以及该物理地址位置是否允许该程序使用。它在逻辑地址而不是物理内存上执行 "integrity checks",因为您可以通过更改逻辑地址并进行操作来检查完整性,但您不能真正在物理内存上执行相同的操作,因为它会影响已经存在的 运行 使用内存的进程。

另外我想提一下,基址寄存器和限制寄存器是通过执行特权指令加载的,特权指令是在内核模式下执行的,只有操作系统才能访问内核模式,因此CPU不能直接访问寄存器。我希望我能帮上一点忙:)

有些事情你需要明白。

首先,CPU无法直接访问物理内存。为了计算物理地址 a CPU 需要一个逻辑地址。然后使用逻辑地址计算物理地址。所以这是逻辑地址访问物理内存的基本需要。没有逻辑地址,您将无法访问它。这种转换是必要的。假设如果有一个系统不遵循 virtual/logical 地址,该系统将变得非常容易受到黑客或入侵者的攻击,因为他们可以直接访问物理内存并在任何位置操纵有用的数据。

第二件事,当一个进程运行时,CPU 生成逻辑地址以便将该进程加载到主内存上。现在这个逻辑地址的目的是内存管理。与进程的实际大小相比,寄存器的大小非常小。所以我们需要重新定位内存以获得最佳效率。 MMU(内存管理单元)在这里发挥作用。物理内存是MMU使用逻辑地址计算出来的。所以逻辑地址是由进程生成的,MMU根据该逻辑地址访问物理地址。

这个例子会很清楚。

如果数据存储在地址50,基址寄存器的值为50,偏移量为0。现在,MMU将其移至地址100,这也会反映在逻辑地址中。偏移量变为 100-50=50。所以,现在如果需要通过逻辑地址检索数据,它会转到基地址 50,然后查看偏移量,即 50,它会转到地址 100 并访问数据。逻辑地址保存数据移动到的位置的记录。无论数据更改了多少个地址位置,它都会反映在逻辑地址中,因此无论数据现在拥有什么物理地址,该逻辑地址都可以访问该数据。

希望对您有所帮助。

"The integrity of the data on the physical memory could have been preserved by using an algorithm or such which do not allow processes to access or modify memory locations which were already accessed by other processes."

简答:不可能设计出一种有效的算法来匹配相同级别的性能与逻辑地址。

这个算法的问题是你要如何拦截每个进程的内存访问?如果不拦截内存访问,就无法检查进程是否有权访问某个内存区域。如果我们真的要实现这个算法,有一些方法可以在不使用现代 cpus 上的 MMU(内存管理单元)提供的逻辑地址的情况下拦截内存访问(假设你有一个没有 MMU 的 cpu ).但是,这些方法不如使用 MMU 有效。如果你的cpu确实有一个MMU,虽然逻辑地址转换是不可避免的,但你可以设置一对一到物理内存。

在没有 MMU 的情况下拦截内存访问的一种方法是在程序中的每个内存访问指令之前插入内核陷阱指令。由于我们不能信任用户级程序,因此不能将此类工作委托给编译器。因此,您可以编写一个 OS 来完成这项工作,然后再将程序加载到内存中。 OS 将扫描程序的二进制文件并在每次内存访问之前插入内核陷阱指令。通过这样做,内核可以检查是否应该授予内存访问权限。然而,这种方法会大大降低系统的性能,因为每次内存访问,无论合法与否,都会陷入内核。陷入内核涉及上下文切换,这需要很多 cpu 周期。

我们可以做得更好吗?在我们将程序加载到内存之前对我们的程序的内存访问进行静态分析怎么样,以便我们只在非法内存访问之前插入陷阱?但是,进程没有预定义的执行顺序。假设您有程序 A 和 B。它们都试图访问相同的内存区域。那我们的静态分析应该给谁弄呢?我们可以随机分配给其中一个。假设我们分配给 B。那么我们怎么知道 B 什么时候会用完这个内存,以便我们可以给 A 以便它可以继续?假设 B 使用这个区域来保存一个全局变量,该变量在其整个生命周期中被多次访问。是不是等B完成了再把这个区域给A?如果 B 永远不会结束怎么办?

此外,在动态内存分配的情况下,不可能对内存访问进行静态分析。如果程序 A 或 B 试图分配一个大小取决于用户输入的内存区域,那么 OS 或我们的静态分析工具无法提前知道该区域的位置或大小。从而根本无法进行分析。

因此,我们必须回退到捕获每个内存访问并确定访问在运行时是否合法。听起来很熟悉?这是MMU或逻辑地址的功能。但是,对于逻辑地址,当且仅当发生非法访问而不是每次内存访问时才会产生陷阱。