⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4gmem.c

📁 在实地址模式访问4g内存,对了解操作系统底层的人有帮助
💻 C
字号:
#include <dos.h>
///////////////////////////////////////////////////////
//			4G Memory Access
//	This Program Can Access 4G Bytes in DOS Real
//Mode,Needn't in Protection Mode It Works.
//	The Program Enter 32 Bit Flat Mode a moment and
//Only Load FS a 32 Bit Flat Mode Selector,Then Return
//Real Mode.
//	Used The FS Can Access All 4G Memory till It be
//reloaded.
//			--By Southern. 1995.7.17
///////////////////////////////////////////////////////

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
};
unsigned char	OldIDT[6]={0};		//Save The IDTR before Enter Protect Mode.
unsigned char	pdescr_tmp[6]={0};	//NULL The IDTR,IDTR's Limit=0 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 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>
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");
		}
}
main()
{
	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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -