ImageVerifierCode 换一换
格式:DOCX , 页数:8 ,大小:18.77KB ,
资源ID:26591932      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/26591932.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(在DOS实模式下直接存取4GB内存.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

在DOS实模式下直接存取4GB内存.docx

1、在DOS实模式下直接存取4GB内存在DOS实模式下直接存取4GB内存 作为软件开发人员,大多数对于保护模式都感到神秘和不易理解。本人在开发32位微内核抢占式多线程操作系统过程中,深入了解到CPU的地址机理,在这里将分析CPU的工作原理,解开保护模式的神秘面纱,读者将会发现保护模式其实与实模式一样简单和易于控制。在此基础上用四五十行C语言程序做到进出保护模式和在实模式之下直接访问整个4GB内存空间。虽然有许多书籍对保护模式作解释,但没有一本能简单明了地解释清楚,冗长烦杂的术语让人看着想打瞌睡,甚至还有许多用汇编写的(可能根本不能运行的)保护模式试验程序,事实上用C语言本身就可以做保护模式的进出工

2、作。我们可能知道CPU上电后从ROM中的BIOS开始运行,而Intel文档却说80x86CUP上电总是从最高内存下16字节开始执行,那么BIOS是处在内存的最顶端64K(FFFF0000H)还是1M之下的64K(F0000H)处呢?事实上在这两个地方都同时出现(可用后面存取4GB内存的程序验证)。为什么?为了弄清楚以上问题,首先要了解CPU是如何处理物理地址的?真的是在实模式下用段寄存器左移4位与偏移量相加,在保护模式下用段描述符中的基地址加偏移量而两者是毫无关联的吗?答案是两者其实是一样的。当Intel把80286推出时其地址空间变成了24位,从8086的20位到24位,十分自然地要加大段寄

3、存器才行,实际上它们都被加大了,只是由于保护的原因加大的部分没有被程序看见,到了80386之后地址又从24位加大到32位(80386SX是24位)。整个段寄存器如下图所示:;图1在8086中CPU只有“看得见部分”,从而也直接参与了地址形成运算,但在80286之后,在“看不见部分”中已经包含了地址值,“看得见部分”就退化为只是一个标号再也不用参与地址形成运算了。地址的形成总是从“不可看见部分”取出基址值与偏移相加形成地址。也就是说在实模式下当一个段寄存器被装入一个值时,“看不见部分”的界限被设成FFFFH,基址部分才是要装入值左移4位,属性部分设成16位0特权级。这个过程与保护模式时装入一个段

4、存器是同理的,只是保护模式的“不可见部分”是从描述表中取值,而实模式是一套固定的过程。对于CPU在形成地址时,是没有实模式与保护模式之分的,它只管用基址(“不可见部分”)去加上偏移量。实模式与保护模式的差别实际上只是保护处理部件是否工作得更精确而已,比如不允许代码段的写入。实模式下的段寄存装入有固定的形成办法从而也就不需要保护模式的“描述符”了,因此保持了与8086/8088的兼容性。而“描述符”也只是为了装入段寄存器的“不可见部分”而设的。从上面的“整个段寄存器”可见CPU的地址形成与“看得见部分”的当前值毫无关系,这也解释了为什么在刚进入保护模式时后面的代码依然被正确地运行而这时代码段寄存

5、器CS的值却还是进入保护模式前的实模式值,或者从保护模式回到实模式时代码段CS被改变之前程序是正常地工作,而不会“突变”到CS左移4位的地址上去,比如在保护模式时CS是08H的选择器,到了实模式时CS还是08H但地址不会突然变成80H加上偏段量中去。因为地址的形成不理会段寄存器“看得见部分”的当前值,这一个值只是在被装入时对CPU有用。地址的形成与CPU的工作模式无关,也就是说实模式与0特权级保护模式不分页时是一模一样的。明白了这一机理,在实模式下一样可以处理通常被认为只有在保护模式才能做的事,比如访问整个机器的内存。可以不必理会保护模式下的众多术语,或者更易于理解,如选择器就是“看得见部分”

6、,描述符是为了装入“不可见部分”而设的。作为验证CPU的这种机理,这里写了一个实模式下访问4GB内存的C程序。有一些书籍也介绍有同样功能的汇编程序,但它们都错误地认为是利用80386芯片的设计疏漏。实际上Intel本身就在使用这种办法,使得CPU上电时能从FFFFFFF0H处开始第一条指令,这种技术在286之后的每一台机器每一次冷启动时都使用,只是我们不知道罢了。CPU上电也整个代码段寄存器是这样的:;图2EiP=0000FFF0H这样CSEIP形成了FFFFFFF0H的物理地址,当CPU进行一次远跳转重新装入CS时,基址就变了。为了访问4G内存空间,必须有一个段寄存器的“不可见部分”的界限为

7、4G-1,基址为0,这样就包含了4GB内存,不必理会可见部分的值。显然要让段寄存器在实模式下直接装入这些值是不可能的。唯一的办法是让CPU进入一会儿保护模式在装入了段寄存器之后马上回到实模式。进入保护模式十分简单,只要建好GDT把CRO寄存器的位0置上1,CPU就在保护模式了,从前面所分析CPU地址形成机理可知,这时不必理会寄存器的“看得见部分”值是否合法,各种段寄存器是一样可用的,就像没进保护模式一样。在把一个包含有4GB地址空间的值装入某个段寄存器之后就可返回实模式。预先可建好GDT如下:unsigned long GDT-Table=0,0, /空描述符,必须为零0x0000FFFF,0

8、xCF9A00, /32位平面式代码段0x0000FFFF,0xCF9200 , /32位平面式数据段只是为了访问数据的话只要2个GDT就足够了,因为并没有重装代码段,这里给出3个GDT只是为了完整性。通常在进入保护模式时要关闭所有的中断,把IDTR的界限设置为0,CPU自动关闭所有中断,包括NMI,返回实模式后恢复IDTR并开中断。另外A20地址线的控制对于正确访问整个内存也很重要,在进入保护模式前要让8042打开A20地址线。在这个例子里FS段寄存器设成可访问4GB内存的基址和界限,由于在DOS中很少有程序会用到GS、FS这两个386增加的段寄存器,当要读写4GB范围中的任一个地方都可通过

9、FS段来达到,直到FS在实模式下被重装入冲掉为止。这个例子在386SX、386DX、486上都运行通过。例子里加有十分详细的注释,由于这一程序是用编译连接的,而其连接器不能为DOS程序处理32位寄存器,所以直接在代码中加入操作码前缀0x66和地址前缀0x67,以便让DOS实模式下的16位程序可用32位寄存器和地址。程序的右边以注释形式给出等效的32位指令。要注意16位的指令中mov al, byte ptr BX的指令码正好是32位的指令mov al, byte ptrEDI。读者可用这个程序验证BIOS是否同时在两个区域出现。如果有线性定址能力的VESA显示卡(如TVGA9440)还可进一步

10、验证线性显示缓冲区在1MB之上的工作情况。#include unsigned long GDT-Table=0,0, /NULL - 00H0x0000FFFF,0x00CF9A00, /Code3- 08h Base=0 Limit=4G-1 Size=4G0x0000FFFF,0x00CF9200 /Data3- 10h Base=0 Limit=4G-1 Size=4G;unsigned char OldIDT 6=0; /Save The IDTR before Enter Protect Mode.unsigned char pdescr-tmp 6=0; /NULL The IDT

11、R s Limit=0 CPU will/ disable all Interrupts, include NMI.#define KeyWait() while(inportb(0x64) &2);void A20Enable(void)keyWait ();outportb(0x64,0xD1);KeyWait();outportb(0x60,0xDF); /Enable A20 with042.KeyWait();outportb(0x64,0xFF);KeyWait ();void LoadFSLimit4G(void)A20Enable (); /Enable A20/*Disabl

12、e ints & Null IDT/*asm CLI /Disable inerruptsSIDT OldIDT /Save OLD IDTRLIDT pdescr-tmp /Set up empty any interrupts, / Include NMI./*Lodd GDTR/*asm / The right Code is Real, But BC+ s Linker NOT/ Work with2bits Code.db 0x6/3bit Operation Prefix in 1Bit DOS.MOV CX,DS /MOV ECX,DSdb 0x6/Get Data segmen

13、t physical AddressSHL CX,/SHL ECX,4MOV word ptr pdescr-tmp 0,(3*8-1)/MOV word ptr pdescr-tmp 0, (3*8-1)db 0x66XOR AX,AX /XOR EAX,EAXMOV AX,offset GDT-Table/ MOV AX,offset GDT-Tabledb 0x66ADD AX,CX /ADD EAX,ECXMOV word ptr pdescr-tmp 2, AX/GDTR Base low1bitsdb 0x66SHR AX,1/SHR EAX,16MOV word ptr pdes

14、cr-tmp 4,AX/GDTR Base high1bitsLGDT pdescr-tmp /Load GDTR/*/* Enterbit Flat Protected Mode/*asmmov DX,0x10 / The Data3Selectordb 0x66,0x0F,0x20,0xC0 / MOV EAX,CR0db 0x66MOV BX,AX / MOV EBX,EAXOR AX,1db 0x66,0x0F,0x22,0xC0/MOV CRO,EAX / Set Protection enable bitJMP Flsuh /Clear machine perform cache.

15、flush: / Now In Flat Mode, But The CS is Real Mode Value.asm /And it s attrib is 16Bit Code Segment.db 0x66MOV AX,BX /MOV EAX,EBXdb 0x8E,0xE/MOV FS,DX/Load FS Base=0 Size=4G nowdb 0x66,0x0F,0x22,0xC0 /MOV CRO,EAX/Return Real Mode.LIDT OldIDT /LIDT OldIDT /Restore IDTRSTI / STI /Enable INTRunsigned c

16、har ReadByte (unsigned long Address)asm db 0x66asm mov di,word ptr Address / MOV EDI, Addressasm db 0x6/3bit Address Prefixasm db 0x6/FS:asm mov al,byte ptr BX / =MOV AL, FS: EDIreturn -AL;unsigned char WriteByte(unsigned Long Address)asm db 0x66asm mov di,word ptr Address /MOV EDI, Addressasm db 0x6/3bit Address Prefixasm db 0x6/FS:asm mov byte ptr BX,al /=MOV FS: EDI,ALreturn -AL;/ Don t Touch Above Code /# include void Dump4G (unsigned long Address)int i;int j;for (i=0; i (作者地址:珠海巨人集团电脑排版公司) 作者:梁肇新

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1