首页 > 解决方案 > Linux asm - int 16h 模拟读取原始键盘扫描码

问题描述

对于我的学习,我需要在 asm 上编写一个程序,它会等到键盘按键被按下,然后打印它的扫描码和按键字符的 ASCII 码。

我知道 BIOSint 16h可以完成这项工作,但我现在使用的是 Linux,找不到合适的模拟系统调用。

我应该用什么来完成这项任务?我目前正在为我的汇编代码使用 Debian Stretch 和 NASM。

标签: linuxassemblykeyboardnasmscancodes

解决方案


通常,内核将键盘扫描码转换为您可以在 tty 上读取的 ASCII 字符。但是有一些方法可以获得原始扫描码,例如在文本控制台上 查看showkey(1)它是如何(http://kbd-project.org/ )的。https://wiki.archlinux.org/index.php/Keyboard_input

https://github.com/legionus/kbd/blob/2.0.4/src/showkey.c显示您可以使用ioctl(2)控制台终端的文件描述符将KBD翻译模式设置为RAW(扫描码)或MEDIUMRAW (键码)。然后就可以进行正常read的系统调用了。

ioctl(fd, KDSKBMODE, show_keycodes ? K_MEDIUMRAW : K_RAW)

syscall显然,您可以在 x86-64 或32 位 x86 上使用手写 asm 进行这些系统调用,int 0x80在 中查找系统调用号asm/unistd_64.h,以及在它们各自的标头中的其他常量的值。


showkey注意设置看门狗计时器以干净地退出并捕获信号,因为这样做会在内核处理 control-C 或 ctrl+alt+f2 序列之前拦截键。因此,如果没有超时,就无法退出程序。如果您在没有恢复正常模式的情况下退出,则无法在控制台上键入运行命令来恢复正常键盘模式。


推荐阅读