内存模型

文章来源:Intel software developer’s manul V1: Chapter 3.3 MEMORY ORGANIZATION

当应用程序要访问内存时,并不能直接对物理内存进行寻址,而是需要根据实际情况(例如操作系统的具体实现)来选择以下三种内存模型中的其中一种。另外,在现代的Linux 内核中,通常使用第一种也就是平坦内存模型。

Flat memory model

flat(平坦) 内存模型下,在应用程序的视角里,内存有一个独立且连续的内存空间。这种地址空间又被称作linear address space(线性地址空间)。这种模型中,所有的代码、数据和栈都在同一个地址空间中,且直接提供字节级别的寻址。在没有启用64-bit 的情况下,最大可寻址范围是 0 ~ 2^{32}-1. 在线性地址空间下的每一个字节的地址都被称作线性地址。

Segmented memory model

Segmented(分段)内存模型下,在应用程序的眼中,内存被组织为被称为“段”的一组独立地址空间。代码、数据和栈在这种模型下通常被置于独立的内存段中。应用程序通过logical address(逻辑地址)来对每个不同段里的字节进行寻址,逻辑地址通常又被叫做”far pointers”。逻辑地址包括segment selector(段选择器)和offset(偏移量),段选择器用于标识要访问的字节所在的内存段,而偏移量指向字节在该内存段中的位置。在32-bit 的处理器中,最多支持16383个不同大小和类型的内存段,且每个段最大都可以支持2^{32} 个字节大小的内存。

在处理器内部,实际上所有的内存段都被映射到线性地址空间中,在访问内存时,处理器会将逻辑地址翻译为线性地址,只不过这个过程对应用程序而言是透明的。

起初设计分段内存模型的目的,是为了给应用程序和操作系统提供更高的可靠性,通过将不同用途的内存置于各自的内存段中,可以有效的进行隔离。例如,如果在这种模型下发生栈溢出,不用担心栈溢出后会覆盖代码段或数据段,避免运行错误的指令或损坏数据。

Real-address mode memory model

实地址模式内存模型主要用于运行早期的为8086 处理器编写的程序,目的是为了提供兼容性。它是一种分段内存模型的特殊的实现,对于每个要运行的程序或操作系统,它可以提供一组每个大小不超过64KB 的内存段。这种模式下线性地址空间最大仅能支持到2^{20} 字节。

最后提供一张图片来更好的理解这三种不同的内存模型: