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位寄存器。