<Int 16h> Linux 中的 GCC 程序集导致 BIOS 中断?

<Int 16h> BIOS interruption with GCC Assembly in Linux?

我正在使用 QTCreator 3.5.1 和虚拟 OS,即 Linux Mint 18.3 Cinnamon 32 位,GCC 编译器。

我必须编写一个使用中断的代码,使用汇编命令获取键盘上按下的键。

本应在 windows 上运行的代码如下所示:

#include <iostream>
unsigned char x;
int main()
{
 do {
 __asm {
 mov ah, 00h
 int 16h
 mov x, ah
 };
 std::cout <<"The pressed key code is "<< x << std::endl;
 } while (true);
}

尽管它在 Windows 98(使用 Visual Studio 2003 在 Windows 7x32 上编译)和任何其他 Windows 系统上都不起作用,但给了我一个 运行时间错误或关闭我的系统(在 Windows 98)。

所以我切换到 Linux 并且来自 http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html(第 7 部分)的以下汇编示例代码工作得非常好:

#include <iostream>
using std::cout;
int main(void)
{
        int foo = 10, bar = 15;
        __asm__ __volatile__("addl  %%ebx,%%eax"
                             :"=a"(foo)
                             :"a"(foo), "b"(bar)
                             );
        printf("foo+bar=%d\n", foo);
        return 0;
}

(为了使其正常工作,我还必须在 QT Creator Tool->Options 的“Desktop Kit”上指定编译器版本(usr/bin 中的 GCC x86 32 位)和 4.8 的工作 QT 版本.7,最后一个版本 5.5.1 给我一个“未正确安装,请 运行 make install”错误)

虽然我很难理解中断的概念以及“int 16h”中断应该如何在 linux 上使用 GCC 内联汇编工作,但语法是什么以及如何获得任何按下的键盘键代码?

对于现代系统;在启动期间,OS 从固件中控制所有硬件,然后固件将无法使用(因为可以假定硬件的 none 处于固件期望的状态)。然后 OS 启动它自己的为 OS 设计的驱动程序,并使用 IRQ 并与操作系统调度程序一起工作(不要浪费 CPU 时间轮询),并为multi-CPU,并正确支持内存(不限于 640 KiB)。

这意味着 BIOS 中断“int 0x16”只能在以下任一情况下工作:

a) 您使用的 OS 在 20 多年前变得无关紧要 (MS-DOS)

b) 你使用的 OS 做了很多额外的工作来模拟 20 多年前变得无关紧要的 OS(例如“旧版 DOS 兼容性" 内置于 Windows95,而不是任何用于 Windows 的 Windows 可执行文件。

c) 您没有使用 OS,并且计算机太旧以至于固件是 BIOS(较新的计算机改为切换到 UEFI)。

I have to write a code that uses interruptions, obtaining a key pressed on the keyboard using assembly commands.

我会仔细检查你应该做什么。例如。 “使用中断”可能意味着“使用旧的 32 位 Linux 内核 API(int 0x80)而不是过时的 BIOS 函数”(并且它可能意味着“使用过时的 PS/2 控制器芯片 IRQ(就像设备驱动程序那样)”,或其他东西)。

更具体地说;我猜你遵循了包括“在虚拟机中安装旧的 32 位版本的 Linux” 的说明,因为你应该使用旧的 Linux 内核 API ("int 0x80") 在汇编语言中做相当于 "read(STDIN_FILENO, buffer, 1);" 的操作(从任何 stdin 中获取一个字节,它可能来自也可能不来自键盘,具体取决于您的可执行文件的方式started/used).

服务int 16h是一个BIOS服务。它只在实模式下工作,通常用于引导装载程序或 DOS 程序。它不能从 Windows(任何版本,除非执行 DOS 程序,在这种情况下服务被模拟)或 Linux(任何版本)或任何其他保护模式操作系统访问。

根据 Freenode 上#winapi 上的人员的说法,可能可以从 Windows 98 上的 Win32 程序调用 int 16h,但调用可能会导致 BIOS 挂起.无论如何,这对实现您的目标没有用。

要解决您的问题,请使用 ia16-gcc、Open Watcom 或旧版本的 MSVC 等 DOS 工具链编写 DOS 程序,或者使用您正在编程的操作系统支持的保护模式服务.