标题:请教regs的问题
只看楼主
ehyyngp
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2005-11-25
 问题点数:0 回复次数:1 
请教regs的问题

union REGS regs;
regs.x.ax = 3;
int86(MOUSE, &regs, &regs);
return(regs.x.bx);

这是什么意思 对regs中各个变量赋值,不同的值代表什么含义,出口参数值又代表什么呢,请高手指点

那里有这方面的教程啊?

搜索更多相关主题的帖子: regs REGS 变量 
2005-12-14 10:49
ChenMo
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:3
帖 子:481
专家分:10
注 册:2004-4-8
得分:0 

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 的组合键。

#include <stdio.h>
#include <conio.h>
#include <dos.h>

#define RSHIFT 1 /* 右 Shift 键 */
#define LSHIFT 2 /* 左 Shift 键 */
#define CTRL 4 /* Ctrl 键 */
#define ALT 8 /* Alt 键 */
#define SCROLLLOCK 16 /* Scroll Lock 键 */
#define NUMLOCK 32 /* Num Lock 小键盘锁键*/
#define CAPSLOCK 64 /* Caps Lock 大小写转换状态键 */

int main(void)
{
int InNum = 0x16;
union REGS InRegs;
union REGS OutRegs;

printf("Check the keyboard's status:\n");

/* 接收键盘输入 */
while( getch() != 'q' )
{
clrscr();
printf("Check the keyboard's status:\n");

InRegs.h.ah = 2;
int86(InNum, &InRegs, &OutRegs);

/* 判断键盘状态 */
if ( OutRegs.h.al & RSHIFT )
puts("Right Shift");
if ( OutRegs.h.al & LSHIFT )
puts("Left Shift");
if ( OutRegs.h.al & CTRL )
puts("Ctrl");
if ( OutRegs.h.al & ALT )
puts("Alt");

if ( OutRegs.h.al & SCROLLLOCK )
puts("Scroll Lock (On)");
else
puts("Scroll Lock (OFF)");

if ( OutRegs.h.al & NUMLOCK)
puts("Num Lock (On)");
else
puts("Num Lock (Off)");

if ( OutRegs.h.al & CAPSLOCK)
puts("Caps Lock (On)");
else
puts("Caps Lock (Off)");
}

puts("\nPress any key to exit.");
getch();
return 0;
}

[此贴子已经被作者于2005-12-15 14:42:08编辑过]


欢迎加入 MVC 技术讨论群(新群:90093426)
2005-12-14 12:44



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-38070-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.120053 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved