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();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章