Search code examples
c++linuxassemblygccbios

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


I'm using QTCreator 3.5.1 and a virtual OS which is Linux Mint 18.3 Cinnamon 32-bit, GCC Compiler.

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

The code that should've been working on windows is like this:

#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);
}

Although it doesn't work on either Windows 98, compiled using Visual Studio 2003 on Windows 7x32, and any other Windows systems, giving me a runtime error or shutting my system down (on Windows 98).

So I switched to Linux and the following assembly example code from http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html (part 7) is working pretty much fine :

#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;
}

(For it to work properly I also had to specify the compiler version (GCC x86 32bit in usr/bin) on "Desktop Kit" in QT Creator Tool->Options and a working QT version which is 4.8.7, the last version 5.5.1 giving me a "non properly installed, please run make install" error)

Although I struggle to understand the concept of interruptions and how should the "int 16h" interruption work on linux with GCC inline assembly, what is the syntax and how I can obtain any pressed keyboard key code?


Solution

  • The service int 16h is a BIOS service. It only works in real mode and is usually used in boot loaders or DOS programs. It cannot be accessed from neither Windows (any version, unless executing a DOS program in which case the service is emulated) or Linux (any version) or any other protected mode operating system for that matter.

    According to the folks on #winapi at Freenode, it might have been possible to call int 16h from a Win32 program on Windows 98, but the call might then produce a hang in the BIOS. Anyway, this is not useful for achieving your goal.

    To solve your problem, either write a DOS program using a DOS toolchain such as ia16-gcc, Open Watcom, or an old version of MSVC, or use a protected mode service supported by the operating system you are programming for.