割り込みハンドラ

interrupt 修飾子を指定することにより、プロセッサ割り込みによって呼び出される関数を定義できます。
#include <stdio.h>
#include <dos.h>
void interrupt handler( void ) {
  printf( "ハンドラが呼び出されました\n" );
}
int main() {
  setvect( 0x40, handler );
  union REGS regs;
  int86( 0x40, &regs, &regs ); // ハンドラの呼び出し
  handler(); // 直接呼び出すこともできます
  return( 0 );
}

interrupt 関数は、ret 命令ではなく iret 命令で帰還します。また、interrupt 関数の先頭で AX, CX, DX, BX, SP, BP, SI, DI ES, DS の各レジスタが順にスタックへプッシュされ、末尾で DS, ES, DI, SI, BP, SP, BX, DX, CX, AX が順にポップされます。AX レジスタが必ず保存されるため、interrupt 関数から値を返すことはできません。その他は通常の関数と同じです。

interrupt 関数を直接呼び出すこともできます。この場合は、pushf 命令が call 命令の前に付加されます。medium/large モデルでは、push cs 命令も付加されます。

large 以外のメモリ モデルでは、interrupt 関数に制御が渡されたときの cs および ds レジスタの値に注意してください。たとえば、上のコードでは interrupt 関数内で printf を呼び出しているため、small/compact モデルの場合は cs レジスタの値が重要です。また、small/medium モデルの場合は、メッセージ文字列に正しくアクセスできるように ds レジスタを既定値に維持する必要があります。