How to make interruption handler in C
06:31 12 Dec 2025

I have this C code:

void print_hello(void);
void far int_handler(void);

void kernel(void)
{
    // Set interruption handler in IVT
    *((unsigned short*)(0x30 * 4)) = (unsigned short)int_handler;
    *((unsigned short*)(0x30 * 4 + 2)) = (unsigned short)(((unsigned int)int_handler) >> 16);

    _asm
    {
        int 0x30        ; My interruption
        xor ah, ah      ; Wait for keypress
        int 0x16
        int 0x19        ; Continue booting
    }
}

void print_hello(void)
{
    const char* str = "Hello, World!\r\n\0";

    while (*str)
    {
        char c = *str;
        _asm
        {
            mov al, c       ; AL = character
            mov ah, 0x0E    ; Teletype output function
            mov bh, 0x00    ; Page number
            mov bl, 0x07    ; Text attribute (0x07 = light gray on black)
            int 0x10        ; BIOS video interruption
        }
        str++;
    }
}

void far int_handler(void)
{
    print_hello();
}

I compile it with Watcom:

wcc -0 -d0 -mc -s -wx -zl kernel.c
wlink FILE kernel.obj FORMAT RAW BIN NAME kernel.bin OPTION NODEFAULTLIBS,OFFSET=4096,START=kernel_

I put the binary in memory into 0x0000:0x1000 address, DS = 0, ES = 0, SS = 0, SP = 0x1000. Everything works, but compiler thinks int_handler() is a regular function, and use retf instead of iret, and because of this stack shifts. How can I fix this?

c assembly x86 x86-16