0

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.

Verloren
  • 859
  • 1
  • 8
  • 18
  • This is not easily possible due to the keyboard being several layers of abstraction away from your program. For a console application, the easiest way is to first set the terminal into unbuffered mode and then to read a single character. This is a bit annoying to do but feasible from assembly. – fuz Nov 23 '18 at 20:32
  • Another approach, which might lead to simpler code but more complex preparations to execute, would be to write a real-mode program that just uses `int 16h` (and other appropriate BIOS features), compile it to a self-contained binary, and install that where the PC's bootloader (often GRUB) can find and execute it. For testing, you could run a virtual PC and use the virtual bootloader to run your binary. – Dave M. Nov 23 '18 at 20:33
  • You might be able to use the "input" subsystem for this. See [man input-events](http://manpages.ubuntu.com/manpages/xenial/man8/input-events.8.html). – Jester Nov 23 '18 at 22:32

1 Answers1

0

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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 1
    Note that this only works in the virtual console, not inside a terminal emulator. – fuz Nov 23 '18 at 20:39