中国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编译问题

内嵌入汇编,但是指令提示
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 楼』:  

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

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





积分 95
发帖 40
注册 2006-10-8
状态 离线
『第 3 楼』:  

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



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





积分 95
发帖 40
注册 2006-10-8
状态 离线
『第 4 楼』:  

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



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

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


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



论坛跳转: