发信人: yangcs()
整理人: yangcs(2000-04-09 19:29:54), 站内信件
|
【 以下文字转载自 CLanguage 讨论区 】 【 原文由 浪子 所发表 】 Windows98 对更早的 Windows 版本最重要的改进可能就是它的连
续32 位寻址。运行于 Windows 3.x 上的 Win16 程序必须把内存分成
段 (segrnmt),这是大小在 16 字节至 64K 字节范围内的内存块。建
立Win16 程序时,开发人员必须努力保证正确使用编译器关键字,诸如
__near 和__far,以建立正确的寻址框架。用 Win32 API 编程的开发
人员再不必考虑这些问题。很少有开发人员在进入 Win32编程生涯,彻
底放弃了 Win16 API 之后,会怀念那令人头疼的分段寻址。
Windows 98 可以运行许多种程序,包括 MS-DOS 程序、Win16 程
序,当然还有 Win32 程序。要完全理解 Intel-86 处理器如何能做到
这些,你必须理解 Intel 用于其32 位 x86 处理器的四种寻址模式。
它们是:实模式、16 位保护模式、32位分页模式和 16 位虚拟 8086
模式。因为 Win32 程序运行于 32 位分页模式,所以我们的讨论也集中
于这种模式。
Intel-86 32 位分页寻址模式
Win32 API 是为支持下面两种内存特征处理器而设计的:32 位寻
址和分页内存。在 Intel-86 系列的处理器中,只有 Intel 80386 及
其以后的 CPU 满足这些要求。更早的处理器(包括 8088 和 80286)
都不能支持 Win32 的内存特性需求,因而也不能运行 Windows 98。
这个处理器系列的更新成员,包括 80386、i486 和 Pentium(奔
腾芯片),都满足这两个要求。所有这些处理器都支持一种页大小,4K。
因此,运行于 Windows 98下的 Win32 程序必须使用这种页大小。
但是,不要认为所有的Win32实现都使用4K 的页。例如,Digital
的 Alpha 处理器(一种运行 Windows NT 的平台)就具有 8K 的页。
Win32 被设计成可以支持其他页大小,包括 16K 页和 32K 页。如果创
建 Win32 软件时因故依赖于 4K 的页大小,那么运行在非 4K 页的处
理器上时就会产生不兼容性。
我们将要讲述的寻址方案基本上是针对 Intel 处理器的固定方案。
因为它代表着用于分页式虚拟内存的合理方案,所以 Windows NT 也采
用了同样的手段,甚至运行于非 Intel 处理器时也是这样。
虚拟地址的三个构成部分
Intel 32 位分页寻址把 32 位地址分成三个部分使用。一个 32
位的地址包括一个 12 位部分和两个 10 位部分。为了帮助你理解它怎
样工作,我们从低 12 位讲起。
我们从低 12 位讲起,是因为它们最简单,因而最容易理解。它们
描述单个内存页中的偏移量。我们已经说过,页的大小为4K,凭感觉就
知道,2 的 12 次方是4K(4096)。每个页不过就是有 4K 个项的字
节数组。当然,一个 12 位的地址并不能达到目的。要存储任何达到有
用数量的信息,都需要多个页。
我们可以使用 32 位虚拟地址的中间 10 位来访问更多的页。那10
位用作一个称为页表(page table)的特殊内存页中的偏移量。每个页
表驻留在一个 4K 的内存页中。它可以引用 1024 个存放应用程序的代
码和数据的其他页。二者合在一起,这个 22 位的地址可以寻址 4MB的
RAM。尽管 4MB 曾经是很大的内存,但现在却一点也不显大了。要访问
处理器的全部地址空间,我们必须使用虚拟地址中的最后 10 位。
32 位地址的高 10 位被用作另一个页表的变址。但是这个页表很
特殊,因为它指向其他页表,而不是指向代码或数据页。因此,它有一
个特殊的名称:页目录(page directory)。象其他页表一样,页目
录包含的是 32 位值的数组。合计起来,可以用给定页目录寻址的页表
数目达到 1024 个。如果你会做算术,就会知道,一个页目录可以引用
多达 4GB 的内存。正如你所知道的,这就是 32 位 Intel-86 CPU 的
地址空间。
令人费解的另一个问题是寻址机制是怎么知道如何开始的。也就是
说,它怎么知道哪个页存放着页目录呢?页目录是用一个名叫 CR3 的特
殊 CPU 寄存器来引用的。(还存在 CR0、CR1 和 CR2 寄存器,不过
它们的用法超越了我们的讨论范围。)CPU 靠操作系统软件来管理这个
寄存器的内容。这就是为什么有不同内存方案的不同操作系统都可以在
Intel x86 处理器上运行的原因。操作系统中,可以在 Intel 处理器
上运行的有 MS-DOS、16 位 Windows 3.x、Windows NT、UNIX、OS/2
和 iRMX(一个 Intel 的操作系统)等。
Translation Lookaside Buffer
在我们开始讨论特定于 Windows 98 的内存管理问题之前,还需要
再对分页寻址说一两点。看上去很明显,对独立内存位置的每次访问都
需要访问另外两个内存位置:一个页目录和一个页表。这将使访问分页
内存的耗时是访问非分页内存的三倍。
如果不是处理器维护着一个高速缓存,叫做 TLB(translation
lookaside buffer),存储着最近使用过的页表项,这就会成为事实。
这个高速缓存的大小随处理器的不同而不同, 但通常都很小。 例如,
486 的 TLB 可以缓存最多 32 个页表项。通过这些项可以引用 128K
代码或数据。
事实证明,这样少量的高速缓存在大多数情况下是足够了,因为大
多数软件都表现出被称作“局部引用”的特点。换句话说就是,大多数
软件对小数据集合的处理都在一系列小循环中进行。高速缓存命中率达
到 95% 或更高就可以使内存与寻址有关的性能问题相当少见,但并不
能完全消除。
尽管大多数软件都倾向于以 TLB 可以适应的方式工作,但并不能
保证每个程序都这么做。根据我们对内存寻址的讲述,可以很容易地写
出一段使 TLB 无效的软件。例如:分配 33 页 RAM,然后以闭环方式
循环处理。基于这种内存访问方案的程序和那些考虑 TLB 作用的程序
相比,其运行速度将显著降低。在为你自己的软件设计内存的组织与访
问方式时,不要忘了这一点。
-- 欢迎您到C语言版来!
欢迎光临BBS系统版!
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.99.93.6] -- ※ 转载:.月光软件站 http://www.moon-soft.com.[FROM: 210.72.45.12]
|
|