|
关于内存的一些基本概念
看了如是大师的“config系统的配置文件讲解”的关于内存部分,对内存了解了一些,无奈基础差,另文中有些用词前后不统一,一些概念仍难理解。
今日看到一本dos方面的书,里面一些内容似乎能帮助一些新手对内存的理解。
因此OCR了部分相关内容,整理出来,供参考。
原文见:实用DOS大全358问
OCR: lianjiang
************************************
342.DOS是怎样进行内存管理的?
内存是计算机中存储程序代码以及数据的地方,是程序赖以运行的舞台。内存在计算机中编址,形成了内存地址空间,既包括了RAM内存,也包括了ROM内存。通常的内存编址方法是按字节(8bit进行的,1M内存便是指大小为1兆字节的内存空间。以PC机为例,早期的8086/8088系统共有20根地址线,则可寻址2^20=1M字节;80286系统则有24根地址线,相应可寻址2^24=16M字节,到了386、486,地址总线宽度扩大到了32根,可寻址的内存空间也扩大为4G字节。
内存地址空间又称为物理地址空间,它是实际主存储器的大小;相对有虚拟地址空间的概念,也称逻辑地址空间,它指的是应用程序的编级地址空间。二者有时等同,有时相互区别,这取决于系统的内存管理策略。
无论是早期的DOS版本,还是最近的6.22;DOS下直接使用的都是物理地址空间。如果要使用逻辑地址空间,你必须自己编程。这一点,我们后面还要讲到。
DOS是单用户单作业操作系统,因此采用的是固定分区内存管理技术,把内存低端部分(1M以下)固定地分成系统区和用户区(TPA),见图4-3。
当前版本的MS—DOS可以管理1MB的物理地址空间。在IBMPC及其兼容机上,由MS-DOS和其他程序所占的内存在地址0000H处开始,并可达地址09FFFFH,此640KB的RAM区域有时称为“常规内存区”。此地址以上的内存区是为ROM硬件驱动程序、视频刷新缓冲区等所保留的。非IBM兼容机有可能使用其他内存区段。在MS—DOS控制下的RAM区可分成两个主要部分:
操作系统区域
临时程序区域(TPA)
操作系统区域在地址0000H处开始,即它占用RAM的最低部分。该处有中断向量表、操作系统模块及其所拥有的表(table)和缓冲区,以及config.sys)文件中指定的附加可安装设备驱动程序及command.com命令解释程序的驻留部分。操作系统区所占的内存量随MS-DOS版本、磁盘缓冲区数、可安装设备驱动程序个数与大小而改变。
临时程序区为RAM中所存操作系统区上面的剩余部分,是动态可分配的内存。DOS将在应用程序运行时总是试图把这部分内存分配给它,必要时系统区1(参见图4—3)将腾出以扩大TPA区。如果此区过小,则会出现。out of memory内存不够的错误,你的应用程序将无法运行。
当出现此错误时,在低版本DOS中将是一筹莫展,在8086/8088中亦是如此,最多能做到的是不装载任何TSR程序。这意味着你甚至需要牺牲鼠标器支持;而高版本DOS则可以利用将要讲到的两点功能(1)把DOS自身一部分装载到HMA中,(2)把TSR程序和驱动程序装载到UMB,从而达到扩大TPA,供应用程序运行的目的。
对于1M以上的内存,DOS将无能为力,除了下面将要讲到HMA以外。
================================================================
343.为什么在386、486的计算机上虽然有4M或更多的内存配置,却总是会出现“内存不够”的错误?
这正是DOS的局限性所带来的。从前面的问题中我们可以看出,在DOS中,真正供应用程序运行区域是TPA。DOS为了保持与8086/8088系统兼容性,把TPA限制在1M以下.所以有时计算机虽有4M或更多内存,你也无法直接使用。当然,1M以上的内存也还是可以利用的。
(1)在保护模式下,你可以直接寻址1M以上空问。DOS是无法做到这一点,而Windows或OS/2等其他操作系统可以做到。
(2)利用DOS提供的工具,间接访问1M以上空间,如EMS或XMS技术。关于EMS和XMS请参见《如何使用扩充内存(Expanded)》和《如何使用扩展内存Extended)》。
===============================
346.什么是常规内存、扩充内存、扩展内存?
常规内存(Conventional Memory)是指从00000H到9FFFPH这640k的内存空间,它是DOS的传统势力范围.DOS对这一段的划分和管理请参阅《DOS是怎样进行内存管理的》。
扩充内存(Expanded Memory)是一种不参与存储器统一统址的内存。其使用规范称作EMS(Expanded Memory Sepecfication),因为是由Lotus,Intel和Microsoft三家公司联合开发的,故也称作LIM EMS。早期XT机型上扩充内存以内存卡的物理形式出现,后来的高档微机上则可以由扩展内存(Extended Memory)来仿真扩充内存,这是CPU开始支持内存映射的结果。
扩展内存是原1MB内存空间的纵向延伸.这种内存只存在于80286以上的机型之中。这种内存,只是在“保护(protected)”方式时是可寻址的;DOS运行于real方式(实模式),仿真8086寻址空间,因此标准的DOS应用程序是不能直接访问它的。对286来说,CPU共有24根地址线,其扩展内存可达15MB,而在386,486或更高档机器上。扩展内存可拥有4GB-1MB的大小,这是因为它们的地址总线宽度为32位。
===============================
347 如何使用扩充内存(Expanded Memory)?
因为扩充内存没有统一编址,所以CPU不能象访问普通的主存那样通过地址线来直接访问它。这中间就需要扩充内存管理程序EMM,也既是软件技术的支持。
对扩充内存的访问有些像日常去图书馆借书。你是没有权力进入书库象查检自己的书柜那样进行“访问”的,只有去到柜台那儿,交给管理员小姐您的索书单,她便进库去找寻您要的书,找到之后回来再为您办理手续——如果把书库看作您自家书柜这一主存的扩充内存的话,管理员小姐便是EMM,您便是CPU。柜台呢,则称作页框.
页框的大小是64K,为什么是64K呢?您一定记得8086的段式访问机制,一个段的大小便是64k。这样,只要知道了页框起始处的段地址,就可以通过一个偏移量指针遍历整个页框,如果超过64K,那就需要调整段地址了.
或许EMS的设计者考虑到内存的使用效率而把扩充内存以16k为单位进行组织划分,而不是一个页框的大小。现在EMS内中的每16k就称作一页,那么CPU同时也就只能“看见”扩充内存其中四页,虽然程序可以申请到不止四页的扩充内存。这自然类似于图书馆的制度,您可以“借”图书馆的许多书,甚至全部的书,但一次您只能“惜到”十本书,看完归还之后再来借.
编程中对扩充内存进行访问的步骤大致如下:
(1)EMM安装了没有?
无论是EMM386.EXE还是QEMM386.SYS等EMM程序,具有统一的设备名“EMMxxxx”,我们可以通过判断此设备是否安装来判断EMM存在与否?
(2)页框起始地址在何处?
这是判断EMM已安装后的第二个步骤。页框是我们“看到”EMS内存的窗口,当然首先要找到它。
(3)申请EMS内存
如果您估计您的程序数据量不会超过1MB,那就申请64页的扩充内存好了(当然要实际存在如此多的扩充内存才可以,EMM不可能无中生有),申请到的EMS内存由一个称作句柄的整数来标志管理.
当然您可以随时根据需要多次申请EMS内存,只不过处理多个句柄总是要多些麻烦。
(4)映射EMS内存
申请到了一些EMS内存页面,意味着你可以“看”它们,但迄今为止它们并不“可见”,还需要进行映射。映射的意思,也就告诉EMM,让它把哪一个句柄的哪四页(少一些页自然可以),放到页框这个窗口中来。
做完映射工作之后,您就可以往页框中存放,读取数据了.当这几页用完之后.再映射其它几页到页框中,而原来的四页则不再‘可见’。如此这般,您就可以把您大量的数据存放到EMS内存中。
(5)释放EMS内存
当工作完成之后,还需要把申请到的EMS内存加以释放,因为EMM无法判断程序的结束而主动地来完成这项工作。
这一系列步骤使得EMS内存的使用看起来有些麻烦。的确,EMS内存的使用在一定程度上降低了系统性能.但这是值得的,要知道世界上没有免费的午餐.
。。。。。。
==================================
348.如何使用扩展内存(Extended Memory)?
早期在DOS下访问扩展内存,必须通过BIOS中断INT l5H,但是因为该接口功能不够严谨,各软件之间容易因为使用扩展内存而发生冲突.有鉴于此,1988年底Microsoft, Intel,Lotus和AST四家公司共同开发出了关于存取扩展内存的标准,这就是扩展内存规范XMS(Extended Memory Specification).
为了兼容性,大多数XMS驱动程序都可以为INT l5H保留一席之地.
DOS及DOS应用程序无法直接访问扩展内存,必须通过XMS功能接口达到目的.
XMS编程大致可分以下几个步骤:
(1)判断XMS是否已安装
这一点可以通过调用INT 2FH的4300H 号子功能来实现,通常INT 2FH以其“假脱机打印”功能而闻名。
功能调用之后,若寄存器AL=80H 表示XMS驱动程序已安装,反之则否.
(2)申请XMS内存块 ’
XMS编程接口有一点很特殊,不同于一般的中断调用,就是各子功能的执行是要对XMS驱动程序入口点进行远调用,而不是中断调用.
XMS驱动程序的入口地址可以通过INT 2FH的子功能4310H号来得到.调用完毕后,ES:BX即为入口点.
。。。。。。
(3)数据的存取
申请到了扩展内存,但我们并不能直接使用它,仍需要先把数据存放在一个常规内存缓冲区内,待恰当时机再把数据从缓冲区移到扩展内存之中.这一点对应XMS的0BH 号子功能:移动扩展内存块。
(4)释放扩展内存
该子功能号为0AH,入口参数为要释放的扩展内存块的句柄.
对于上面的讨论,请进一步阅读有关资料,以得到更详尽的信息.
下面给出一个完整的例子,供你参考。
。。。。。。
==================================
349.什么是UMB? 如何使用UMB?
640K~1MB这一段地址空间是微机的设计者保留下来给系统以及外部扩展设备来使用的,因此在这一段之中没有系统板上的RAM.如果您的机器配置了1MB的内存,并且机器没有打开明SHADOW功能的话,将会有384k的扩展内存,此时RAM最高地址为1408K。
这一段地址空间某些部分的分配是比较固定的:
。。。。。。
其他部分的地址空间则没有固定地被占用,由其他硬件扩展设备,如汉卡、网卡等等来选择.一般情况下,这些空闲地址空间可用来再生成上位内存块UMB,供DOS利用.
让我们来看一个VGA配置的PC兼容机有多大的空闲空间。首先B000—B7FF这一段32k的空闲,再就是从C800开始到EFFF结束的这一段,大小为160k——所以我们总共可以有192KB的空间提供给DOS。如果再算上HMA 64K的话,就意味着DOS拥有
了896k=(640+192+64)K 的空间!
事情总要打点折扣,首先如果你安装了网卡,便只有牺牲16K的大小(通常情况);如果您的应用程序需要扩充内存,或者通过扩充内存卡获得,或者通过EMM386.exe等类似的EMM程序利用扩展内存来仿真得到,但都必须在640k--1MB这一段的空闲区内生成一个EMS页框,又会占去64K的大小.
另外一个问题是保留内存中的空闲区并不连续,在插入其他插卡后有可能被再次分割.如果一个网卡占用了E000~E3FF这16K,原选160k的连续空闲区将被分割为两块,一块96K,一块48K。这就使得DOS在把驱动程序、内存驻留程序装载到UMB运行时,不可避免地造成空间浪费,不能充分利用.
这儿是用MSD察看保留内存区的一个例子。
。。。。。。
保留内存区又称上位内存区UMA,所以利用其间的空闲地址再生成的RAM块被称作UMB,也就是上位内存块的意思。
为了使DOS能够利用UMB,仅仅在CONFIG.SYS中加载EMM386.exe之类的UMB Provider程序还是不够的,必须再通过命令DOS=UMB在二者之间建立起联系,这样DOS的DEVICEHIGH、LH命令才起作用,DOS的中断功能调用也才能够访问UMB。如果没有在CONFIG中运行DOS=UMB,则利用MSD、MEM等实用程序将无法看到UMB的影子,但此时应用程序可以直接向UMB Provider程序申请使用UMB。
==================================
350,什么是HMA?如何使用HMA?
高位内存区HMA可能是最近人摸不着头脑的东西,它是1MB以上的第一个64K,其实要少16个字节,也就是65520字节的大小.这一段可以为DOS直接访问。
不是说DOS只能直接访问1MB以下的内存区域吗?
我们已知道,DOS的寻址方式是8086/8088的段式机制,16位段地址左移四位再加上16位的偏移量形成20位的地址。这样问题便来了,1MB的绝对地址可以写成段:偏移量的形成为FFFF:000FH,也就是该段起于1MB空间的最后一小节FFFF0H 处;如图4-4所示,很明显,该段还有一部分的空间在1MB以上,也就是扩展内存之内.为FFFF:000FH只是该段的第一个小节结束的地方;偏移量还有FFF0的“余量”,
这“余量”确定的空间显然可以由DOS直接访问,只得把编移量累加上去就行了.该段的1MB以上区域便是HMA,很显然其大小为64K-16B.
从绝对地址的角度看,HMA的第一个字节地址FFFF:0010H 已是21位地址宽度:1000000H.这在8086/8088中将产生地址绕回错误,因为8086/8088只有20根地址线,
第21根子虚乌有,所以1000000H 处即为00000H 处.这样,“HMA”便成了0000:0000H至0000:FFEFH这一段!
早期的一些应用程序利用这一点来作为特殊技巧,达到所需的编程效果,也就是说,它们依赖于地址回绕.所以,到了后来的286、386等机器,虽然CPU拥有了24根、32根的地址总线,解决了8086/8088中16位地址进位超出总线宽度的问题,却为了保持兼容性,并没有把HMA区直接向DOS开放,而是通过—个“开关”进行控制.
这个“开关”便是我们常常见到的A20 line。A20便是第21根地址线,众所周知,计算机中的总线都是从0开始编号的.
DOS下HMA区的管理由HIMEM.SYS来提供。程序可以控制A20 line的开、关,可以申请使用HMA,但有一点,HMA不能分割使用,也就是说一次只能有一个程序在其间运行.如果在CONFIG.SYS文件中加载了HIMEM.SYS驱动程序并且同时有DOS=high命令时,MS-DOS将使A20线有效,并为HMA直新定位系统代码.
。。。。。。
笔者建议在编程中不要试图去使用HMA,免得遇到很多不必要的麻烦,利用HMA的最理想方法便是通过在CONFIG.SYS中加载HIMEM.SYS并运行DOS=high命令,把MS-DOS系统代码加载至其中,从而腾出更多的常规内存来.在DOS 6.2版本中,DOS=high命令可腾出约49K的空间出来.
关于HMA的使用和编程,请进一步阅读有关的详细资料.
=============================
351.如何使用HIMEM.SYS?
HIMEM.SYS是一扩展(Extended)内存管理程序,也就是常说的XMM,它为扩展内存的使用提供了统一接口标准XMS,避免了早期扩展内存使用当中存在的冲突问题;同时HIMEM.SYS还提供对HMA的管理.
HIMEM.SYS必须在CONFIG.SYS中首先加载,这一点很容易理解,在EMM386.EXE加载之后,保留内存区持有UMB出现,HIMEM.SYS也提供对UMB进行管理的接口.如果在CONFIG.SYS没有运行DOS=UMB命令,也即没有建立起DOS和UMB之间的联系时,应用程序可以直接向HIMEM.SYS申请使用UMB.
HIMEM.SYS在CONFIG.SYS中的语法是:
。。。。。。
=============================
352.如何使用EMM386.EXE?
EMM386.EXE利用扩展(Extended)内存来仿真扩充(Expanded)内存,以提供对需要扩充内存的应用程序的支持,同时它还提供UMB功能,使得一些设备驱动程序和内存驻留程序能够加载至UMB中,从而腾出更多的常规内存。
EMM386.EXE在CONFIG.SYS中必须位于HIMEM.SYS之后来加载,因为它依赖于HIMEM.SYS的扩展内存支持。这二者也都必须使用DEVICE来加载,而不是DEVICEHIGH,这是因为DEVICEHIGH依赖于EMM386.EXE提供的UMB功能。同理,要在AUTOEXEC.BAT中使用LOADHIGH(LH)命令也必须在CONFIG.SYS中已加载EMM386.EXE前提之下,并使用DOS=UMB命令在DOS和UMB之间建立起联系。
EMM386.EXE在CONFIG.SYS中的语法分:
。。。。。。 |
|