Here is an interrupt handler running in protected mode using DJGPP. This is modified slightly from the DJGPP User's Guide

//Simple Example of chaining interrupt handlers
//Adopted from Matthew Mastracci's code 

#include <stdio.h>
#include <pc.h>
#include <dpmi.h>
#include <go32.h>

//macros by Shawn Hargreaves from the Allegro library for locking
//functions and variables.
#define LOCK_VARIABLE(x)    _go32_dpmi_lock_data((void *)&x,(long)sizeof(x));
#define LOCK_FUNCTION(x)    _go32_dpmi_lock_code(x,(long)sizeof(x));

//timer interrupt 8 is generated every 18.2 ms
#define TIMER 8

//global counter
int counter = 0;

//the new ISR, will be called automatically every 18.2 ms once installed

void TickHandler(void)

void junk(void)

int main(void)
//structures to hold selector:offset info for the ISRs 
   _go32_dpmi_seginfo OldISR, NewISR;
   int old_counter = 0;

   printf("About to chain the new ISR onto the old timer ISR..\n");

//lock the functions and variables

//load the address of the old timer ISR into the OldISR structure
   _go32_dpmi_get_protected_mode_interrupt_vector(TIMER, &OldISR);
//point NewISR to the proper selector:offset for handler
   NewISR.pm_offset = (int)TickHandler;
   NewISR.pm_selector = _go32_my_cs();

//chain the new ISR onto the old one so that first the old
//timer ISR
//will be called, then the new timer ISR
//notice no changes to counter in this loop- the interrupt changes it
   while (!kbhit())
	    while(old_counter == counter) ;
		old_counter = counter;

   printf("Removing new ISR from the timer ISR chain\n");

//load the old timer ISR back without the new ISR chained on

    return 0;