中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
作者:
标题: 内嵌入汇编,tc编译问题 上一主题 | 下一主题
beiyuly
初级用户





积分 95
发帖 40
注册 2006-10-8
状态 离线
『楼 主』:  内嵌入汇编,tc编译问题 使用 LLM 解释/回答一下

内嵌入汇编,但是指令提示
instructions not enabled

用的是tc3.0

请教是为什么?

代码如下,实模式下访问4G虚拟内存

/**************************************************************/

#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;
}




http://beiyu.bokee.com
2007-4-19 06:39
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 2 楼』:   使用 LLM 解释/回答一下

访问4G内存,要32位CPU吧?
编译要设成80386


2007-4-19 09:35
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
beiyuly
初级用户





积分 95
发帖 40
注册 2006-10-8
状态 离线
『第 3 楼』:   使用 LLM 解释/回答一下

问题解决了。在编译的时候,用tcc.exe,然后用参数 -1,表示使用80186/286汇编,英文是
80186/286 instructions




http://beiyu.bokee.com
2007-4-19 23:16
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
beiyuly
初级用户





积分 95
发帖 40
注册 2006-10-8
状态 离线
『第 4 楼』:   使用 LLM 解释/回答一下

具体参数说的是用186/286指令还是不用,没有具体说明




http://beiyu.bokee.com
2007-4-19 23:17
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: