阳光网驿-企业信息化交流平台【DTC零售连锁全渠道解决方案】

 找回密码
 注册

QQ登录

只需一步,快速开始

扫描二维码登录本站

手机号码,快捷登录

手机号码,快捷登录

老司机
查看: 1454|回复: 7

[原创] 让CPU在实模式下获得4G访问能力的最简单代码

[复制链接]

该用户从未签到

发表于 2009-10-30 10:50:25 | 显示全部楼层 |阅读模式
;以下内容由cxdzxc---创作于2008-11-22
;这个程序由MASM6.15编译通过,生成的文件需要在DOS下执行,COM文件可以正确执行,EXE会死机或重启
;执行此程序后,恭喜你,你可以在实模式下访问4G的地址空间了
;要访问4G空间需要使用指令---MOV ESI,#data(#data是任意的不超过32位的立即数)
;---MOV AX,ES:[ESI] ;在程序执行后的实模式下,请不要使用像---MOV ES,AX这样的指令(不能重装ES),否则将丧失4G的访问能力
;传播请保留全部的信息,有什麽问题(表述或者程序有错误的话)请联系---QQ GROUP 83372198 QQ:750347821 ;EMAIL:750347821@QQ.COM,
;CXDZXC@GMAIL.COM

.386P                  ;这个伪指令指出下面的代码兼容了80X386保护模式以上的代码,要操作保护模式的寄存器,
                           ;数字后面必须要有个字母P
   CSEG SEGMENT USE16 ;USE16这个伪指令指出代码段CS是使用16位的段,因为.386P伪指令的默认是32位段,
                          ;这里要改一下默认
   ORG 100H      ;这里设定标号START开始的地址是100H,某些编译器可以不用这行
   START: cli      ;关中断,这个很重要,否则别怪我言之不预
   in al,0eeh       ;通过读0EEH端口打开A20地址线
   mov ebx,cs     ;将代码段寄存器中的值装入到EBX中
   shl ebx,4         ;将EBX中的段值左移4位
   add dword ptr cs:GDTR+2,ebx ;将EBX中已经左移了4位的段值加上GDTR表中在编译时得到的GDT表开始的偏移地址,
                          ;得到GDT表开始的32位物理地址, 并装入到GDTR表相应的内存单元中,MASM5.0好象不能这样用
   LGDT fword ptr cs:GDTR ;将GDT表的32位物理地址和GDT表的长度装入到GDTR中, ;一点说明:MASM5.0---LGDT必须使用QWORD;
                           ;这是MASM5.0的BUG,MASM6.11,MASM6.15---LGDT必须使用FWORD,这是不一样的地方
   mov eax,cr0    ;取出CPU工作模式控制寄存器CR0里的参数到EAX中
   or al,1            ;将PE(保护模式有效位)设为1 mov cr0,eax ;将新的值传入到CR0(CPU工作模式控制寄存器)中,使PE位生效 MOV dx,8
                          ;因为要留出一个空描述符的位置,所以数据段描述符在GDT表中的偏移地址位置是8
   MOV ES,dx    ;将数据段描述符装入到ES段寄存器中,实模式下使用ES段寄存器来访问0-4G,这样可以方便使用串操作
   and al, 0FEh  ;准备关闭PE位
   MOV CR0,EAX ;将新的值传入到CR0(CPU工作模式控制寄存器)中,使PE位无效
   ret                 ;返回到DOS,DOS自己会开中断,这里STI我就不写了^_^,如果把这段代码用在其它程序中, ;这一行也可以不用了
;--------------------------------------------------------------------------------------------------------------
DATA_SEL dw 0ffffh,0000,9300h,00CFh ;这里是数据段的描述符
GDTR DW $ - DATA_SEL-1+8,DATA_SEL-8,0  ;这里减1是正好才能指到GDT的边界上, 加8是要加一个空描述符的位置,
                        ;中间部分减8是正好指向GDT表开始的16位偏移地址, ;如果再将代码段值左移4位加上这个值就是GDT表的32位物理地址值了
                        ;GDT的长度(在前面的一个字---即16位)和基址(在后面的两个字---即32位),共48位
CSEG ENDS ;代码段结束伪指令 END START ;这个伪指令指出程序的执行要从START标号处开始,并到这里结束
;------------------------------------------------------------------------------------------------------------
;这里对A20的操作作下说明---A20在最早只是为了在段的边界是1M(即0FFFFFH)时实现地址的回饶,
;否则如果在实模式里打开A20,DS=0FFFFH,IP=0FFFFH时,FFFF0H+FFFFH=10FFEFH,
;10FFEFH+1(地址0也是一个访问单元)=10FFF0H(就是可以访问到总共10FFF0H个内存单元,这样就会超过1M了)
;而关闭A20,当生成的地址超过0FFFFFH时,地址会回绕到00000H开始,在运行上面的程序扩展段边界到4G以后,
;如果不开A20,当访问100000H-1FFFFFH之间,300000H-3FFFFFH之间,500000H-5FFFFFH之间时...,
;会访问到与奇数兆-1兆的偶数兆上,即:访问100000H-1FFFFFH之间的区域时, 会访问到00000H-0FFFFFH之间对应的区域上,
;访问300000H-3FFFFFH之间时,会访问到200000H-2FFFFFH之间对应的区域上,访问500000H-5FFFFFH之间时,会访问到
;400000H-4FFFFFH之间对应的区域上...其实就是第21的根(A20)地址线要和控制位(关闭A20,这个位就变为0)进行与操作
;控制A20有3种方法,1:操作键盘控制器,2:操作92H端口,3:操作0EEH端口,这个程序使用操作(读)0EEH端口的方法打开A20,
;这是CSDN的---xiaopoy---给我说的,如果有什麽问题的话,你找他去吧!^_^
;------------------------------------------------------------------------------------------------------------
;这里对数据段描述符的值作下说明,前面的4个F是段边界限制地址的0-15位,中间4个0的位置是段开始地址的0-15位,
;其中的93表示这是特权级0-段存在的可读写数据段,93后面的00是段开始地址的16-23位,CF前的00是段开始地址的24-31位,
;其中的C表示这是32位4G边界限制段,它和前4个F和最后一个F(这个F位置是段边界限制地址的19位-16位,
;表示这是最大0fffffh+1(0值也对应了一个页面)(1M)*4kb(分页)=4G的段
;只要不重装段值,段高速缓存区的地址生成(访问方式)就不会改变,这是我这样写代码的依据!!!-----CR0的工作模式位改变时,
;只是立即改变了段重装(请注意我说的是重装,如果没有这个动作,地址的生成方式就不会改变)段值时,
;段的装入内容(实模式装的是段值,保护模式装的是段的描述符)和段的装入方式(实模式是左移4位装入高速缓存区,
;保护模式是取出描述符里的段基值装入高速缓存区)
;--------------------------------------------------------------------------------------------------------------
;设置CR0以后,如果没有改变要使用的数据段和代码段的值,就可以不用JMP,也就是说不用清除CPU的指令队列,
;这个要保证指令队列中也不能有重装与程序相关的段的描述符这样的操作,这个可以从代码的组成中去满足这一条件
;(就是说程序只要没有那样做,指令队列里就不会有),这样不用JMP,程序也可以正确执行
;--------------------------------------------------------------------------------------------------------------
;结后语,实模式的代码段理论上也可以通过类似的重装代码段描述符,将16位的IP扩展为32位的EIP,使代码在4G范围内段内转移,
;但不能直接使用软件(软中断可以从中断向量表中取值,计算出确定的物理地址,而间接使用软中断)和硬件中断(这个也可以变通),
;也不能直接使用出栈的RET操作指令(但这同样可以变通的,通过读取SP所指向内存单元中的值,而得到正确的程序转移地址),
;感兴趣的朋友可以自己试一下 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cxdzxc/archive/2008/11/25/3372494.aspx

[ 本帖最后由 cxdzxc 于 2009-10-30 12:27 编辑 ]
4G_DOS.jpg

4g_dos.rar

176 Bytes, 下载次数: 2

楼主热帖
启用邀请码注册,提高发帖质量,建设交流社区
  • TA的每日心情
    奋斗
    2015-5-8 17:53
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    发表于 2009-10-30 11:58:57 | 显示全部楼层
    看得头晕,有没简单点的
    启用邀请码注册,提高发帖质量,建设交流社区

    该用户从未签到

     楼主| 发表于 2009-10-30 12:25:53 | 显示全部楼层
    原帖由 yixinemail 于 2009-10-30 11:58 发表
    看得头晕,有没简单点的

    这个已经是最简单的了,不算伪指令的话,真正的代码才16行
    启用邀请码注册,提高发帖质量,建设交流社区
  • TA的每日心情
    擦汗
    2011-2-23 16:02
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2009-10-30 12:33:04 | 显示全部楼层
    能不能图片不要收费啊
    看看怎么回事
    启用邀请码注册,提高发帖质量,建设交流社区

    该用户从未签到

     楼主| 发表于 2009-10-30 12:40:03 | 显示全部楼层
    原帖由 卡萨最后一夏 于 2009-10-30 12:33 发表
    能不能图片不要收费啊
    看看怎么回事

    你回复一下的稿费就可以换一锭阳光币,所以1锭银子不多的哈^_^
    启用邀请码注册,提高发帖质量,建设交流社区
  • TA的每日心情
    开心
    2024-6-7 12:48
  • 签到天数: 903 天

    [LV.10]以坛为家III

    发表于 2009-11-1 21:39:38 | 显示全部楼层
    真可以这样么?有实践过的?
    启用邀请码注册,提高发帖质量,建设交流社区
  • TA的每日心情
    开心
    2016-9-1 11:51
  • 签到天数: 38 天

    [LV.5]常住居民I

    发表于 2009-11-2 01:20:35 | 显示全部楼层
    下载怎么多书本上的东西,能学完。。。。。。。。。
    启用邀请码注册,提高发帖质量,建设交流社区

    该用户从未签到

     楼主| 发表于 2009-11-2 09:31:11 | 显示全部楼层
    原帖由 oico 于 2009-11-1 21:39 发表
    真可以这样么?有实践过的?

    实践过,这样就可以访问1M---4G以内的地址了,话说没实践过我敢发到这里来说事的么..........

    cxdzxc 于 2009-11-2 09:32 补充以下内容

    原帖由 attmasong 于 2009-11-2 01:20 发表
    下载怎么多书本上的东西,能学完。。。。。。。。。

    貌似不知你所云啊.......

    [ 本帖最后由 cxdzxc 于 2009-11-2 09:34 编辑 ]
    启用邀请码注册,提高发帖质量,建设交流社区
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    快速回复 返回顶部 返回列表