转自: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(); } |