int86相關(Borland C++)

 轉自:http://hi.baidu.com/zhongji/blog/item/1bf5820a55f14d3cb1351dc4.html

 

REGS 是聲明(描述) Intel 80x86 CPU 16位通用寄存器的一個內部結構(還包括標誌位寄存器,標誌位寄存器一般用作設置或獲得錯誤)。

一般的用途是:向中斷接口提供一個參數寄存器組。

該結構會在int86()函數、int86x() 函數、intdos() 函數及intdosx()函數中被使用到,這四個函數已在頭文件 dos.h 中被聲明,詳細使用方法請網友自行參閱相關文檔或書籍。

簡而言之,80x86 16位通用寄存器包括:
    AX,BX,CX,DX,SI,DI,SP,BP(最後的 SP 和 BP)在C中沒有被聲明。

此外,AX,BX,CX,DX 分別分爲高位字節(High)與低位字節(Low),
分別是(左邊爲高位字節,右邊爲低位字節):
    AX{AH,AL}
    BX{BH,BL}
    CX{CH,CL}
    DX{DH,DL}

無論是 16 位的寄存器(AX,BX ……),還是 16 位寄存器的高低位字節(8位寬)(AH,AL,BH,BL……),
並沒有明確地說明各個寄存器的作用,而常規地,尤其在 CPU 中斷指令等地方,那些寄存器有各自特定的用途。

在C語言中的 REGS 結構如下:

union REGS
{
    struct WORDREGS x;
    struct BYTEREGS h;
};

明顯地,REGS 是由兩個另外的結構封裝而成,WORDREGS 結構及 BYTEREGS 結構。而 WORDREGS 如下:

struct WORDREGS
{
    unsigned int ax, bx, cx, dx, si, di, cflag, flags;
};

unsigned int 一般在16位字長CPU下的編譯器被定義尺寸是16位(2字節)的。ax,bx,cx,dx,si,di 在前面已有說明,而 cflag 與 flags 用於標誌寄存器。

BYTEREGS 如下:
struct BYTEREGS
{
    unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};

分別是前面說的各寄存器的高位字節與低位字節的描述,以 unsigned char 類型來聲明是因爲,高位字節與低位字節都是8位寬。

聲明一個 REGS 結構類型的變量後,如 REGS regs;可以使用用 WORDREGS 結構的 x 來訪問或設置16位寄存器,如 regs.x.dx = FP_OFF(FarVar);使用 BYTEREGS 結構的 h 來訪問16位寄存器的高位或低位字節,如 regs.h.ah = 9;可能需要說明一下:FP_OFF 是一個宏,用於設置偏移地址,事實上,它的作用是轉換 FarVar 這遠指針爲 unsigned int 類型。此外還有 FP_SEG 宏,用於設置段地址,而該宏也是先將指針轉換爲32位無符號長整型(unsigned long)後,右移16位,將結果再轉換爲 unsigned int 類型。

下面會給出一個例程,該例程說明如何在 int86() 函數中使用 REGS 結構,而其它的函數可以參考相關的文檔或書籍。

int86() 函數的功能是提供通用的8086軟中斷接口,其原型是:
 
int86(int intno, union REGS* inregs, union REGS* outregs);
intno 參數指定中斷號,inregs 與 outregs 分別是入口參數寄存器和出口參數寄存器。入口參數提供信息,結果則從出口參數中獲取——可能入口與出口是同一組寄存器,這是允許的。

下面的例程檢測鍵盤的狀態,判斷哪些功能鍵(Shift, Alt, Ctrl, Num Lock, Caps Lock)被按下過。程序調用int86()函數來使用 Int 16h 的功能2 —— 取鍵盤標誌字節,該功能把一字節值返回到 AX 的低位字節(AL 寄存器)中,該字節各個位描述了鍵盤的功能鍵狀態(On/Off)

下面的程序的用法說明一下,下面的程序在運行後,
按任意鍵開始檢測,按小寫 ‘q’結束;
開始只能看到 Num Lock, Caps Lock 及 Scroll Lock 三個功能開關的狀態,
按任意鍵繼續檢測,
而如果想要檢測到 Shift、Alt、Ctrl 這些功能鍵,需要按住它們,然後再按任意其它鍵,再鬆開所有鍵,即可被檢測到,
需要注意的是,可能有些 Windows 組合鍵會被觸發。如按住 Alt 然後按其它任意鍵開始檢測,但是如果任意地剛好按中了 Space(空格),那麼將會激活窗口的系統菜單,所以儘量避免使用 Windows 的組合鍵。

/*------------------------------------>>>
*//*很多學C的朋友對C語言下編寫的鼠標程序感到神奇,但對它的實現卻又很迷惘,其實它的原理很簡單,以下就是我編寫的一個TC圖形下的鼠標菜單界面程序中的鼠標驅動部分,而整個程序也將很快和大家見面。
*//*Author : Cifry
*//*------------------------------------>>>*/
#include<dos.h>
#include<conio.h>
#include<graphics.h>
#include<bios.h>
getmouse()
{
        union REGS inregs,outregs;
        while(!bioskey(1))
        {
        inregs.x.ax=3;
        int86(0x33,&inregs,&outregs);gotoxy(2,6);printf("%-3d,%-3d",outregs.x.cx,outregs.x.dx);
        mouse_pointer(outregs.x.cx,outregs.x.dx);
        }

}
mouse_pointer(int mouse_x,int mouse_y)
{
        int pixi,pixj;
        static int revert_x,revert_y;
        int _x,_y;
        static int savimage[16][16];
        static int flag=1;
        int mose_pot[16]={
                                0x0003,0x000D,0x0032,0x00C2,
                                0x0304,0x0C04,0x3008,0xC008,
                                0x4010,0x2010,0x1020,0x0820,
                                0x0440,0x0240,0x0180,0x0080,
                        };
        if(flag==1)
        {
                revert_x=mouse_x;
                revert_y=mouse_y;
                for(pixi=0,_y=mouse_y;pixi<16;pixi++,_y++)
                for(pixj=0,_x=mouse_x;pixj<16;pixj++,_x++)
                savimage[pixi][pixj]=getpixel(_x,_y);

                for(pixi=0;pixi<16;pixi++)
                {
                        int test=0x0001;
                        for(pixj=0;pixj<16;pixj++)
                        {
                                if((mose_pot[pixi]&test)!=0)putpixel(mouse_x+pixj,mouse_y+pixi,15);
                                test<<=1;
                        }
                }

                flag=0;
        }
        if((mouse_x!=revert_x)||(mouse_y!=revert_y))
        {
                for(pixi=0;pixi<16;pixi++)
                {
                        int test=0x0001;
                        for(pixj=0;pixj<16;pixj++)
                        {
                                if((mose_pot[pixi]&test)!=0)putpixel(revert_x+pixj,revert_y+pixi,savimage[pixi][pixj]);
                                test<<=1;
                        }
                }

                revert_x=mouse_x;
                revert_y=mouse_y;
                for(pixi=0,_y=mouse_y;pixi<16;pixi++,_y++)
                for(pixj=0,_x=mouse_x;pixj<16;pixj++,_x++)
                savimage[pixi][pixj]=getpixel(_x,_y);

                for(pixi=0;pixi<16;pixi++)
                {
                        int test=0x0001;
                        for(pixj=0;pixj<16;pixj++)
                        {
                                if((mose_pot[pixi]&test)!=0)putpixel(mouse_x+pixj,mouse_y+pixi,~savimage[pixi][pixj]&0x00FF);
                                test<<=1;
                        }
                }
        }
        for(pixi=0;pixi<64;pixi++)
        {
                for(pixj=0;pixj<64;pixj++)
                {
                        putpixel(pixj+4,pixi+4,savimage[pixi/4][pixj/4]);

                }
        }

}
word()
{
        int x=100,y=150;
        char author[]="Author : Cifry";
        char qq[]=    "OICQ   : 442044866";
        char email[]= "Email : [email protected]";

        settextstyle(0,0,4);
        setcolor(BLUE);
        outtextxy(x,y,"M");
        setcolor(GREEN);
        outtextxy(x+=32,y,"0");
        setcolor(CYAN);
        outtextxy(x+=32,y,"U");
        setcolor(RED);
        outtextxy(x+=32,y,"S");
        setcolor(MAGENTA);
        outtextxy(x+=32,y,"E");
        setcolor(BLACK);
        outtextxy(x+=32,y," ");
        setcolor(BROWN);
        outtextxy(x+=32,y,"M");
        setcolor(LIGHTGREEN);
        outtextxy(x+=32,y,"a");
        setcolor(LIGHTCYAN);
        outtextxy(x+=32,y,"g");
        setcolor(LIGHTRED);
        outtextxy(x+=32,y,"n");
        setcolor(LIGHTMAGENTA);
        outtextxy(x+=32,y,"i");
        setcolor(YELLOW);
        outtextxy(x+=32,y,"f");
        setcolor(WHITE);
        outtextxy(x+=32,y,"i");
        setcolor(BLUE);
        outtextxy(x+=32,y,"e");
        setcolor(RED);
        outtextxy(x+=32,y,"r");
        x=400;y=250;
        settextstyle(0,0,0);
        setcolor(WHITE);
        outtextxy(x,y,author);
        outtextxy(x,y+=20,qq);
        outtextxy(x,y+=20,email);
}
main()
{
        int gdriver,gmode;

        gdriver=VGA;
        gmode=VGAHI;
        initgraph(&gdriver,&gmode,"");
        rectangle(0,0,72,72);
        word();
        getmouse();
        getch();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章