Assembly 什么是i.h.ah、o.h.ah和int86?

Assembly 什么是i.h.ah、o.h.ah和int86?,assembly,dos,x86-16,bios,turbo-c++,Assembly,Dos,X86 16,Bios,Turbo C++,我正在尝试理解一个程序来获取箭头键。 代码如下: int getkeys( ) { union REGS i,o; while(!kbhit( )); i.h.ah=0; int86(22,&i,&o); return(o.h.ah); } 谁能给我解释一下这个密码吗。这是为了得到箭头键,但我没有得到这段代码。它调用BIOS中断16h,函数00h,即“读取按键” 当此中断调用返回时,A

我正在尝试理解一个程序来获取箭头键。 代码如下:

int getkeys( )
{
       union REGS i,o;
       while(!kbhit( ));
            i.h.ah=0;
       int86(22,&i,&o);
            return(o.h.ah);
 } 

谁能给我解释一下这个密码吗。这是为了得到箭头键,但我没有得到这段代码。

它调用BIOS中断16h,函数00h,即“读取按键”

当此中断调用返回时,AH将包含按键的扫描代码

int86
表示“呼叫中断”
22
是中断数(16h,表示十六进制16)

i
表示设置为中断的输入寄存器。AH包含函数调用号:0(还有其他调用:)


o
表示从中断设置的输出寄存器。AH被(BIOS)指定为包含按键的扫描代码。

Turbo-C/C++的
int86
功能用于对DOS和BIOS服务进行系统中断调用。
REGS
联合是在中断上下文数据结构中寻址单个寄存器的一种方法。要进行DOS或BIOS调用,需要根据要进行的系统调用的要求在寄存器中设置值。(RBIL)是DOS和BIOS系统调用及其参数和返回值的极好来源。通过以下方式定义
int86

int86
获取要调用的中断号和两个
REGS
联合指针。第一个包含进入中断处理程序时需要设置的值,第二个是检索中断返回的寄存器值的方法

Turbo-C/C++对
REGS
的定义类似于:

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

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

union   REGS    {
    struct  WORDREGS x;
    struct  BYTEREGS h;
};
union的
h
部分只是一种寻址16位寄存器AX、BX、CX和DX的高8位和低8位寄存器的机制,而不是通过
x
通过完整的16位寄存器。此代码:

i.h.ah=0;
int86(22,&i,&o);
只需将AH寄存器(AX的顶部8位寄存器)设置为0,即可进入
int86
函数。此代码:

i.h.ah=0;
int86(22,&i,&o);
正在调用软件中断22(0x16)。如果查看RBIL,您会发现它是BIOS调用:

您将看到此BIOS调用返回AH中按下的下一个字符的BIOS扫描代码,AL是ASCII代码

该行:

return(o.h.ah);
返回从
getkeys


注意:代码
while(!kbhit())在循环中等待,直到检测到按键。Int 0x16/AH=0x00调用用于检索该按键的BIOS扫描代码。

i
o
int86
调用的输入和输出寄存器<代码>ah
是一个寄存器。输入时,它包含“等待按键并读取字符”的功能代码
0
。输出时包含扫描码读取。此处的间距有点误导。如前所述,它看起来像
i.h.ah=0是在while循环内完成的(事实并非如此)。有些人把分号放在一行的while后面,以帮助避免这种混淆。这是另一个很好的例子,开发人员不太关心以后将使用他们的程序的人。我发现这些“x”和“h”选项很差!为什么他们不能选择更合理的“w”和“b”<代码>联合规则{struct WORDREGS w;struct BYTEREGS b;}。我发现写
I.h.dl=65
输出一个字符“a”很笨拙。我觉得讨厌的是h和低寄存器的组合。只是我的想法,很好的回答。第一个投票,然后可能是“w”代表“全部”,而“h”代表“一半”。不管怎样,我喜欢在手册里读这些小东西。这大大提高了我学习新东西的接受度。我真的不喜欢不合逻辑的事情…@SepRoland:脚注是Watcom做出了改变。他们所做的是在16位代码中说,
x
w
是相同的,
h
是一半。因此,完整寄存器是
x
w
(字)是相同的,
h
是一半。在32位代码中,他们修改了
x
,因此它是一个DWORD(完整寄存器),
w
是一个字,
h
是一半。因此,出于处理32位寄存器的必要性,进行了一次更改。出于好奇:那么Watcom是否排除在16位代码中使用32位寄存器?(处理
x
w
相同)@SepRoland是的,watcom排除了在16位代码中使用32位寄存器,这使得调用需要32位寄存器(即使在16位实模式下)的BIOS函数有点困难。不过,我很确定,当使用386 DOS扩展器(即Pharlap)调用real模式/v8086模式以进行BIOS/DOS调用编写32位代码时,数据结构将
x
作为DWORD,将
w
作为字,并且底层函数保存/恢复32位寄存器。