gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 15:20:21 27 4
gpt4 key购买 nike

我试图理解一个程序来获取箭头键。
这是代码:

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

有人可以解释我这个代码。这是为了获得箭头键,但我没有得到这个代码。

最佳答案

Turbo-C/C++ 的 int86函数用于对 DOS 和 BIOS 服务进行系统中断调用。 REGS union 是一种在中断上下文数据结构中寻址单个寄存器的方法。为了进行 DOS 或 BIOS 调用,您需要根据要进行的系统调用的要求在寄存器中设置值。 Ralph Brown's Interrupt List (RBIL) 是 DOS 和 BIOS 系统调用及其参数和返回值的极好来源。 Turbo-C documentation定义 int86这边走:

Name            int86  - general 8086 software interrupt interface

Usage int int86(int intr_num, union REGS *inregs,
union REGS *outregs);

Prototype in dos.h

Description Both of these functions execute an 8086 software
interrupt specified by the argument intr_num.

Before executing the software interrupt, both functions
copy register values from inregs into the registers.

In addition, int86x copies the segregs->x.ds and
segregs->x.es values into the corresponding registers
before executing the software interrupt. This feature
allows programs that use far pointers, or that use a
large data memory model, to specify which segment is
to be used during the software interrupt.

After the software interrupt returns, both functions
copy the current register values to outregs, copy the
status of the system carry flag to the x.cflag field
in outregs, and copy the value of the 8086 flags register
to the x.flags field in outregs. In addition, int86x
restores DS, and sets the segregs->es and segregs->ds
fields to the values of the corresponding segment
registers.

If the carry flag is set, it indicates that an error
occurred.

int86x allows you to invoke an 8086 software interrupt
that takes a value of DS different from the default data
segment, and/or that takes an argument in ES.

Note that inregs can point to the same structure that
outregs points to.

Return value int86 and int86x return the value of AX after completion
of the software interrupt. If the carry flag is set
(outregs->x.cflag != 0), indicating an error, these
functions set _doserrno to the error code.

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;
};
h联合的一部分只是一种寻址 16 位寄存器 AX、BX、CX 和 DX 的高 8 位寄存器和低 8 位寄存器的机制,而不是通过 x 来通过完整的 16 位寄存器。 .这段代码:
i.h.ah=0;

只需将 AH 寄存器(AX 的最高 8 位寄存器)设置为 0 即可传入 int86功能。这段代码:
int86(22,&i,&o);

正在调用软件中断 22 (0x16)。如果您查看 RBIL Int 0x16/AH=x00 你发现这是 BIOS 调用:

KEYBOARD - GET KEYSTROKE
AH = 00h

Return:
AH = BIOS scan code
AL = ASCII character


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

线路:
return(o.h.ah);

返回从 getkeys 按下的字符的 BIOS 扫描码

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

关于assembly - 什么是 i.h.ah、o.h.ah 和 int86?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57834460/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com