消息来源说модель плоской памяти - парадигма, в которой память представляется программе как единое непрерывное адресное пространство. ЦП может напрямую (и линейно) адресовать все доступные без необходимости прибегать к каким-либо видам схемы сегментации памяти или подкачки
。听说现在到处都在使用这样的内存模型,但是程序内存怎么还分成代码段、数据段等等,还有页呢?如果程序是分段的,那是不是意味着我正在使用 分段内存模型?还有平面内存模型与虚拟内存有什么关系,难道不是一回事吗?或者,例如,一个是另一个的实现?
相同的词被用来解释不同的现象。
一个 16 位处理器可以用它的一个寄存器寻址 64 公斤的内存。64 公斤 - 一段。要寻址更多内存,您需要使用两个寄存器 - 一个用于段,另一个用于该段中的偏移量。
还有这样的内存扩展卡,可以通过 64 KB 的窗口进行通信,以及Commodore 机器中的银行切换。
以上都是记忆的分段组织。
事实上,ELF 和 EXE 格式的作者提出了这样的想法,即在他们放置常量、程序代码和堆的地方命名内存片段,也只是在历史上将一个与另一个连接起来 - 因为在旧粘土时代,一对 SS:SP 寄存器指向堆栈并被称为“段堆栈”,而 CS 寄存器例如指向一个代码段(即 .code)。
现在没有人使用几个寄存器(和段寻址),但是将内存划分为段仍然存在,并且从那时起这些术语一直在拖延。
CS\DS\SS\ES\FS\GS
. 如果系统是 32 位的,则描述符中段的大小(限制)为0хFFFFFFFF
(4Gb),基数 =0
. 此限制与 32 位处理器的寄存器大小相同,因此您的来源指出:如果您打开“OllyDbg”调试器,那么在 CPU 寄存器窗口中,您可以找到所有段寄存器的值,包括它们的选择器(可见部分),以及描述符中具有限制的基数。在这里你可以看到除了
FS
基数之外的每个人都是零,极限是最大值。在这种情况下,寄存器 (FS) 有一个基数0x7FFDF000
和一个限制0x0FFF
- 系统将这个段(一个 4K 页大小)分配给TEB进程信息\结构,线程环境块。在这种情况下,只读属性 (R) 设置在段描述符 (FS) 中。所有选择器中的 2-lbit 的值为 (3),表示第三个环的用户应用程序(RPL 位)。页面属性在PTE记录中分配,并且优先于段寄存器描述符中的属性。这就是为什么他们说使用分页,在平面内存模型中,段可以完全被忽略。例如,这里有一段代码专门通过代码段寄存器访问数据段
CS:offset
,虽然理论上应该有一对DS:offset
. 同样,在代码中,您可以浏览DS
. 这再次证实了 RM 中的段寄存器没有发挥任何作用——它们已将所有权力转移到虚拟页面。Flat Flat 是一个从零到最大值的内存模型。具有类似大小的 CPU 寄存器,允许使用单个寄存器寻址所有内存。虚拟内存是一种通过将一个物理页面替换为另一个物理页面来分配 RAM 物理内存的技术(算法)。
系统有一个PFN数据库(PageFrameNumber),每个进程都有自己的树VAD(虚拟地址描述符)和一组工作页面“WorkingSet”。当将不必要的页面驱逐到页面文件时,由于 VAD 和 PFN,系统会跟踪它们属于哪个进程,以便在必要时将它们返回到它自己的内存,而不是其他人的进程(虚拟地址所有进程都相同)。