Keil Logo

Interrupt Functions

The C166 Compiler allows you to write interrupt function in the C language which eliminates the need for assembly language interrupt routine. For example:

void funcname (void) interrupt vector <[>using bankname<]>


funcname is the name of the function.
interrupt indicates that the function is an interrupt function.
vector is the interrupt vector name or trap number.
using specifies which register bank the function uses.
bankname is the register bank name.

The interrupt attribute requires an interrupt vector argument. You may specify an arbitrary interrupt name (whose trap number is specified by the linker INTNO directive), a trap number, or both for the vector. For example:

  • trap_number
  • interrupt_name
  • interrupt_name = trap_number


trap_number is the interrupt vector address divided by 4.

The interrupt attribute affects the object code of the function as follows:

  • On function entry the contents of the SFRs MDC, MDL and MDH (when required) are saved on the stack.
  • If a register bank is specified by the using attribute, the context pointer is saved and the new register bank is selected. Otherwise, all the working registers (Rnn) used during the interrupt function are saved on the stack.
  • When exiting the function all register contents saved on the stack are restored.
  • The RETI instruction (return from interrupt) terminates the function.

The following sample program shows how to use the interrupt attribute and displays the code sequences detailing the prologue and epilogue for this example function. A using attribute is also specified in the example. The generated code switches register banks using the CP register. For example:

stmt level    source

   1          extern bit alarm;
   2          int alarm_count;
   3          extern void alfunc (bit b0);
   5          void falarm (void) interrupt 0x21 using f_regs  {
   6   1        alarm_count++;
   7   1        alfunc (alarm = 1);
   8   1      }


             ; FUNCTION falarm (BEGIN  RMASK = @0x7FFF)
                                           ; SOURCE LINE # 5
0000 C6030300      SCXT    DPP3,#03H
0004 CC00          NOP
0006 F6F00000 R    MOV     f_regs,R0
000A C60800C0 R    SCXT    CP,#f_regs
000E CC00          NOP
0010 EC00          PUSH    DPP0
0012 C6871000      SCXT    MDC,#010H
0016 EC06          PUSH    MDH
0018 EC07          PUSH    MDL
                                           ; SOURCE LINE # 6
001A 248F0000 R    SUB     alarm_count,ONES
                                           ; SOURCE LINE # 7
001E 0FFF          BSET    R15.0
0020 4AFF0000 E    BMOV    alarm,R15.0
0024 CA000000 E    CALLA   cc_UC,alfunc
                                           ; SOURCE LINE # 8
0028 FC07          POP     MDL
002A FC06          POP     MDH
002C FC87          POP     MDC
002E FC00          POP     DPP0
0030 FC08          POP     CP
0032 FC03          POP     DPP3
0034 FB88          RETI
             ; FUNCTION falarm (END    RMASK = @0x7FFF)


  • The interrupt attribute is not allowed when declaring or prototyping external functions. For example, the following function prototype is invalid:
    extern void func (void) interrupt 12;
  • Passing parameters to an interrupt function is not possible. Any attempt to define an interrupt function with arguments generates an error message.
  • Interrupt function declarations may not include a return value. They must be declared with a void return type. The compiler generates an error message if an attempt to define a return value for the interrupt function is made.
  • Your program may not directly invoke an interrupt function. If your program must invoke an interrupt you may use the _trap_ library routine. The _trap_ routine is required to avoid hardware side-effects caused by the RETI instruction that terminates the interrupt function.
  • Interrupt vectors are generated by the linker if a trap number is specified in the interrupt definition. The interrupt vector contains a jump to the interrupt function. You may suppress linker generation of vectors with the NOVECTAB linker directive.
  • All C166 library routines (except serial I/O and memory allocation) are fully reentrant and impose no restrictions on interrupt routines.
  • The C166 Compiler places automatic variables on the stack. Subsequently, C functions that use only automatic variables are reentrant.
  • The compiler never generates absolute addresses for register accesses. Each function is independent of the register bank in use. Therefore, interrupt functions may call any standard C function without restriction.


  • If your interrupt functions are fairly small, it is often more efficient to avoid the using attribute and allow the C166 Compiler to PUSH and POP the registers that are actually used. You may use the CODE compiler directive to compare the code generated with and without the using attribute.
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.