DOS下读取4GB内存
好文章我收集下起来
CPU上电后,从ROM 中的BIOS开始运行。
BIOS是处在内存的最顶端64KB(FFFF0000H),还是1MB之下的64KB(F0000H)处呢?事实上,BIOS在这两个地方都同时出现。
在保护模式时,CS是08H的选择子,到了实模式时,CS还是08H,但地址不会突然变成80H加上偏移量。
也就是说,实模式与0特权级保护模式不分页时是一模一样的。
所以,实模式下一样可以处理通常被认为只有在保护模式才能做的事,比如访问整个机器的内存。
实际上,Intel本身就在使用这种办法,使得CPU上电时能从FFFFFFF0H处开始第一条指令。
程序功能:
- 不需要在保护模式状态下就可以直接把386的4GB内存读出来;
- 利用此程序可直接在DOS中做物理设备的检测。
- 在DOS下,可根据此类方法将中断向量表移到任意位置,达到反跟踪或其他等目的。
程序执行过程:
程序运行后,等用户从键盘输入一个字符。
当输入“Q”字符时,整个程序将退出;
当输入“D”时,将在屏幕上显示一屏内存的数据:
最左边为绝对地址,其后一列显示的是以十六进制位表示的内存的数据,后一列是数据所对应的ASCII码。
代码关键分析:
(1)IP=0000FFF0H
CS∶EIP等于FFFFFFF0H。
(2)段寄存器FS在实模式下无法装入4GB的地址和权限。
所以让CPU进入一会儿保护模式,在装入了FS之后马上回到实模式。
保护模式进入方式:建好GDT,把CR0寄存器的位0置上1。
把一个包含有4GB地址空间的值装入FS之后,就可返回实模式。
(3)预先可建好GDT如下:
unsigned long GDT-Table[]=
{
0,0, //空描述符,必须为零
0x0000FFFF,0xCF9A00, //32位平面式代码段
0x0000FFFF,0xCF9200 //32位平面式数据段
}
(4)进入保护模式时要关闭所有的中断:把IDTR的界限设置为0,CPU自动关闭所有中断,包括NMI。
返回实模式后恢复IDTR并开中断。
(5)A20地址线的控制对于正确访问整个内存也很重要。
在进入保护模式前,要让8042打开A20地址线,否则会出现4GB内存中的混乱。
(6)此程序用BC 3.1编译连接,其连接器不能为DOS程序处理32位寄存器,所以直接在代码中加入操作码前缀0x66和地址前缀0x67,以便让DOS实模式下的16位程序可用32位寄存器和地址。程序的右边以注释形式给出等效的32位指令。
注意:16位的指令中,mov al, byte ptr [BX]的指令码正好是32位的指令mov al, byte ptr[EDI]。
附代码:
#include <dos.h> unsigned long GDT_Table[]= { 0, 0, //NULL - 00H 0x0000FFFF, 0x00CF9A00, //Code32 - 08H Base=0 //Limit=4G-1 Size=4G 0x0000FFFF, 0x00CF9200 //Data32 - 10H Base=0 //Limit=4G-1 Size=4G}; //Save The IDTR before Enter Protect Mode.unsigned char OldIDT[6]={0}; //NULL The IDTR,IDTR's Limit=0 will disable all //Interrupts,include NMI.unsigned char pdescr_tmp[6]={0}; #define KeyWait() {while(inportb(0x64)&2);} void A20Enable(void){ KeyWait(); outportb(0x64,0xD1); KeyWait(); outportb(0x60,0xDF); //Enable A20 with 8042. KeyWait(); outportb(0x64,0xFF); KeyWait(); }void LoadFSLimit4G(void){A20Enable(); //Enable A20 //**************************************//* Disable ints & Null IDT *//************************************** asm { CLI //Disable inerrupts SIDT OldIDT //Save OLD IDTR LIDT pdescr_tmp //Set up empty IDT.Disable any interrupts,Include NMI } //***************************************//* Load GDTR *//*************************************** asm { //The right Code is Real,But BC++'s Linker NOT Work //with 32-bits Code. db 0x66 //32 bit Operation Prefix in 16 Bit DOS. MOV CX,DS //MOV ECX,DS db 0x66 //Get Data segment physical Address SHL CX,4 //SHL ECX,4 MOV word ptr pdescr_tmp[0],(3*8-1) //MOV word ptr pdescr_tmp[0],(3*8-1) db 0x66 XOR AX,AX //XOR EAX,EAX MOV AX,offset GDT_Table//MOV AX,offset GDT_Table db 0x66 ADD AX,CX //ADD EAX,ECX MOV word ptr pdescr_tmp[2],AX //GDTR Base high16 bits db 0x66 SHR AX,16 //SHR EAX,16 MOV word ptr pdescr_tmp[4],AX //GDTR Base high16 bits LGDT pdescr_tmp //Load GDTR} //************************************** //* Enter 32 bit Flat Protected Mode * //************************************** // Set CR0 Bit-0 to 1 Enter 32 Bit Protection //Mode,And NOT Clear machine perform cache,It Meaning //the after Code HAD Ready To RUN in 32 Bit Flat Mode, //Then Load Flat Selector to FS and Description into it's //Shadow register,After that,ShutDown Protection Mode //And ReEnter Real Mode immediately. // The FS holds Base=0 Size=4G Description and //it can Work in Real Mode as same as Pretect Mode, //untill FS be reloaded. // In that time All the other Segment Registers are //Not Changed,except FS.(They are ERROR Value holded in CPU). asm { MOV DX,0x10 //The Data32 Selector db 0x66,0x0F,0x20,0xC0 //MOV EAX,CR0 db 0x66 MOV BX,AX //MOV EBX,EAX OR AX,1 db 0x66,0x0F,0x22,0xC0 //MOV CR0,EAX //Set Protection enable bit JMP Flush } //Clear machine perform cache. Flush: //Now In Flat Mode,But The //CS is Real Mode Value. asm { //And it's attrib is 16-Bit Code //Segment. db 0x66 MOV AX,BX //MOV EAX,EBX db 0x8E,0xE2 //MOV FS,DX //Load FS now db 0x66,0x0F,0x22,0xC0 //MOV CR0,EAX //Return Real Mode.Now FS's Base=0 Size=4G LIDT OldIDT //LIDT OldIDT Restore IDTR STI //STI Enable INTR }} //With FS can Access All 4G Memory Now.But if FS be reloaded //in Real Mode It's Limit will Be Set to FFFFh(Size=64K),//then Can not used it// to Access 4G bytes Memory Again,Because FS is Segment:Offset//Memory type after that.//If Use it to Access large than 64K will generate Execption 0D.//unsigned char ReadByte(unsigned long Address){ asm db 0x66 asm mov di,word ptr Address //MOV EDI,Address asm db 0x67 //32 bit Address Prefix asm db 0x64 //FS: asm mov al,byte ptr [BX] //=MOV AL,FS:[EDI] return _AL;} unsigned char WriteByte(unsigned long Address){ asm db 0x66 asm mov di,word ptr Address //MOV EDI,Address asm db 0x67 //32 bit Address Prefix asm db 0x64 //FS: asm mov byte ptr [BX],al //=MOV FS:[EDI],AL return _AL;} / Don't Touch Above Code /#include <stdio.h>///打印出Address指向的内存中的数据///void Dump4G(unsigned long Address){ int i; int j; for(i=0;i<20;i++) { printf("%08lX: ",(Address+i*16)); for(j=0;j<16;j++) printf("%02X ",ReadByte(Address+i*16+j)); printf(""); for(j=0;j<16;j++) { if(ReadByte(Address+i*16+j)<0x20) printf("."); else printf("%c",ReadByte(Address+i*16+j)); } printf("\n"); } } int main( void ){ char KeyBuffer[256]; unsigned long Address=0; unsigned long tmp; LoadFSLimit4G(); printf("====Designed By Southern.1995.7.17====\n"); printf("Now you can Access The Machine All 4G Memory.\n"); printf("Input the Start Memory Physical to DUMP.\n"); printf("Press D to Cuntinue DUMP,0 to End & Quit.\n"); do { printf("-"); gets(KeyBuffer); sscanf(KeyBuffer,"%lX",&tmp); if(KeyBuffer[0]=='q') break; if(KeyBuffer[0]=='d') Address+=(20*16); else Address=tmp; Dump4G(Address); }while(Address!=0); return 0;}
签名:wak免费电影http://www.wak99.com.
转载于:https://www.cnblogs.com/anakin/archive/2011/12/15/2288792.html
DOS下读取4GB内存相关推荐
- DOS下读取4GB内存——梁肇新代码分析
程序原理: CPU上电后,从ROM 中的BIOS开始运行. BIOS是处在内存的最顶端64KB(FFFF0000H),还是1MB之下的64KB(F0000H)处呢?事实上,BIOS在这两个地方都同时出 ...
- DOS 实方式下直接访问4GB 内存
十堰市湖北汽车工业学院电气工程系(442002) 陈家祺 摘 要: 分析了80486CPU 的寻址机制, 提出了在实方式下直接访问4GB 内存的策略和C 程序设计方法. 关键词: DO S 程序 扩展 ...
- DOS下如何访问4G内存
转载 首先解释几个基本概念: 1.保护模式和实模式 自从1969年推出第一个微处理器以来,Intel处理器就在不断地更新换代,从8086.8088.80286,到80386.80486.奔腾.奔腾Ⅱ. ...
- win7下4GB内存提示:找到4GB,可用2GB的解决方法--让你的win7支持4G内存
今天我给自己的本本扩展了一下内存,但是发现在系统信息中提示"找到4GB,可用2GB"的怪异信息,百度了很久终于悟出了其中的奥妙,在新浪的一篇技术文章中,找到了解决方法,下面是该文章 ...
- dos下的edit命令使用详解
dos下的edit命令使用详解 来源:网络 作者:未知 edit命令是一个简单的编辑软件,我们经常用它来编辑一些程序和批处理文件. 比如,我想在c盘根目录下编辑一个简单的批处理文件,要求无论当前盘和当 ...
- DOS中使用扩展内存与XMS操作库设计
DOS中使用扩展内存与XMS操作库设计 作者:彭学周(Favory.Peng) DOS系统常规内存指的是0-640K的内存区.在DOS下,一般的应用程序只能使用系统的常规内存,因而都要受到640KB内 ...
- 无软驱、光驱,全NTFS分区DOS下最好的GHOST工具maxDOS!!
无软驱.光驱,全NTFS分区DOS下最好的GHOST工具maxDOS!! 本软件的用处.在装好的系统没有DOS的情况下为给装好的WINDOWS 2000/XP/2003装入纯DOS.支持NTFS分区 ...
- 32位系统最大只能支持4GB内存之由来
也许大家对这个问题都不陌生,实际装过系统用过电脑的朋友可能都有这样的经历:自己电脑配的是4G的内存条,可是装完系统之后发现电脑上显示的只有3.2G左右可用内存,其它的内存跑到哪去了?网上也有很多朋友给 ...
- linux tomcat java heap space_Linux下tomcat JVM内存设置
常见的内存溢出有以下两种: java.lang.OutOfMemoryError: PermGen space java.lang.OutOfMemoryError: Java heap space ...
最新文章
- ∇SLAM:自动可微分SLAM
- 过滤内容字段_巧用参数组件和过滤组件,教你快速定位目标数据
- 如何利用抽象工厂更换数据库
- v-for中为什么要有key属性
- Qt笔记-Q_UNUSED解决编译器unused paramenter告警
- 项目管理、bug管理工具 ---禅道使用流程
- C# 动态装载 DLL
- 基于JAVA+SpringMVC+Mybatis+MYSQL的宿舍管理平台系统
- 去中心化数据基础架构Stratos融资183万美元,Spark Digital Capital等参投
- 蛮力法 字符串匹配
- ISO27001适用性-导图
- 一个整合SQL语句的类
- 【2016Esri全球用户大会主题亮点】GIS Apps的交响乐
- 使用Strophe连接xmpp,轻松构建web即时聊天工具
- 猫眼电影的android源代码!,微信小程序入门demo之猫眼电影
- python写android抢票软件,如何用python写一个简单的12306抢票软件
- 计算机动画技术的应用领域,3D动画技术的应用领域
- maya批量操作mel_MAYA运行单个MEL命令方法图文介绍
- php wrap,php wordwrap函数怎么用
- Linux 端口号占用如何处理