11.5 Handles
The modified Harvard architecture of dsPIC30F devices supports two memory spaces of unequal size. Data memory space can be fully addressed with 16 bits while program memory space requires 24 bits. Since the native integer data type (register width) is only 16 bits, there is an inherent difficulty in the allocation and manipulation of function pointers that require a full 24 bits. Reserving a pair of 16-bit registers to represent every function pointer is inefficient in terms of code space and execution speed, since many programs will fit in 64K words of program space or less. However, the linker must accommodate function pointers throughout the full 24-bit range of addressable program memory.
In order to ensure a valid 16-bit pointer for any function in the full
         program memory address space, the MPLAB XC-DSC assembler and
         linker support the handle() operator. The C compiler uses
         this operator whenever a function address is taken. Assembly programmers can use this
         operator three different ways:
mov    #handle(func),w0 ; handle() used in an instruction
.word  handle(func)     ; handle() used with a data word directive
.pword handle(func)     ; handle() used with a instruction word
;directive
      The linker searches all input files for handle operators and constructs a jump table in a section named .handle. For each function that is referenced by one or more handle operators, a single entry is made in the jump table. Each entry is a GOTO instruction. Note that GOTO is capable of reaching any function in the full 24- bit address space. Section .handle is allocated low in program memory, well within the range of a 16-bit pointer.
When the output file is built, the absolute addresses of all functions are known. Each handle relocation entry is filled with an absolute address. If the address of the target function fits in 16 bits, it is inserted directly into the object code. If the absolute address of the target function exceeds 16 bits, the address of the corresponding entry in the jump table is used instead. Only functions located beyond the range of 16-bit addressing suffer any performance penalty with this technique. However, there is a code space penalty for each unused entry in the jump table.
In order to conserve program memory, the handle jump table can be
         suppressed for certain devices, or whenever the application programmer is sure that all
         function pointers will fit in 16 bits. One way is to specify the --no-handles link option on the command line or in the IDE. Another way is to
         define a symbol named __NO_HANDLES in the linker
         script:
__NO_HANDLES = 1;
      Linker scripts for DSC devices with 32K instruction words or less all
         contain the __NO_HANDLES definition to suppress the
         handle jump table.
