Board logo

标题: 内嵌入汇编,tc编译问题 [打印本页]

作者: beiyuly     时间: 2007-4-19 06:39    标题: 内嵌入汇编,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;
}
作者: GOTOmsdos     时间: 2007-4-19 09:35
访问4G内存,要32位CPU吧?
编译要设成80386
作者: beiyuly     时间: 2007-4-19 23:16
问题解决了。在编译的时候,用tcc.exe,然后用参数 -1,表示使用80186/286汇编,英文是
80186/286 instructions
作者: beiyuly     时间: 2007-4-19 23:17
具体参数说的是用186/286指令还是不用,没有具体说明