【发布时间】:2021-04-01 16:51:27
【问题描述】:
我正在使用 QTCreator 3.5.1 和一个虚拟操作系统,它是 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 上运行,在 Windows 7x32 上使用 Visual Studio 2003 编译,以及任何其他 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 32bit)和一个工作 QT 版本,即 4.8.7,最后一个版本 5.5.1 给我一个“未正确安装,请运行 make install”错误)
虽然我很难理解中断的概念以及“int 16h”中断应该如何在带有 GCC 内联汇编的 linux 上工作,但语法是什么以及如何获得任何按下的键盘键代码?
【问题讨论】:
-
当您使用 Qt 时(显然),使用 this 之类的东西不是更合适,而是尝试在 bios 级别捕获键盘事件(不太可能配置在不同操作系统中的相同中断)。
-
int 16h是 BIOS 服务。它仅在实模式下工作,通常用于引导加载程序或 DOS 程序。它不能从 Windows(任何版本,除非执行 DOS 程序在这种情况下模拟服务)或 Linux(任何版本)或任何其他受保护模式的操作系统访问。 -
练习是否指定您必须使用
int 16h?还提供了哪些其他细节?您可以在 Linux 上使用内联汇编读取输入(尽管我不建议在学术练习之外这样做)。在 Windows 上,这也是可能的,但正确的调用取决于 Windows 版本。 -
@fuz,是的。这就是问题所在,我的学术练习确实指定我必须使用 int 16h
-
@IvanSilkin 尝试哄骗 Visual Studio 生成 Win16 或 DOS 应用程序。
标签: c++ linux assembly gcc bios