For my studies I need to write a program on asm, which will wait until the keyboard key is pressed, and then print it's scan-code and ASCII code of the key's character.
I know that BIOS's int 16h
can do the job, but I am using Linux right now and can't find an appropriate analogue syscall for it.
What should I use for this task? I am currently using Debian Stretch and NASM for my assembly code.
Normally the kernel translates keyboard scancodes into ASCII characters that you can read on a tty. But there are ways to get raw scancodes, e.g. look at how showkey(1)
does it (http://kbd-project.org/) on a text console. https://wiki.archlinux.org/index.php/Keyboard_input
https://github.com/legionus/kbd/blob/2.0.4/src/showkey.c shows that you can use an ioctl(2)
on a file descriptor for the console terminal to set the KBD translation mode to RAW (scancodes) or MEDIUMRAW (keycodes). Then you can make normal read
system calls.
ioctl(fd, KDSKBMODE, show_keycodes ? K_MEDIUMRAW : K_RAW)
Obviously you can make these system calls from hand-written asm using syscall
on x86-64 or int 0x80
on 32-bit x86, looking up the syscall numbers in asm/unistd_64.h
, and the values of other constants in their respective headers.
showkey
takes care to set up a watchdog timer to exit cleanly, and catch signals, because doing this intercepts keys before the kernel processes control-C or ctrl+alt+f2 sequences. So without a timeout, there'd be no way to exit the program. And if you exited without restoring normal mode, there'd be no way to type on the console to run a command to restore normal keyboard mode.