9.1 Routine Entry Points

The example code shown above looks similar to that appropriate for a Mid-range device, except for the psect used to hold the increment routine. This psect is associated with a special class that ensures it will be linked in such a way that calls to the label(s) at the start of the psect will work as expected on Baseline devices. This is explained below.

When a call instruction is executed by a PIC Baseline device, bits 0 through 7 of the PC register are loaded from the instruction operand, bits 9 and 10 are loaded from the PA bits in the STATUS register but, importantly, bit location 8 is unconditionally cleared. This implies that call instructions on Baseline devices can only reach addresses that fall in the first 256 locations of any program memory page. In other words, any entry points to callable routines must be located in the first 256 program memory locations of a page. This is also true of any instruction that modifies the PCL register.

Note that this restriction does not affects jumps (goto instructions), which can reach any address. Also note that this restriction does not prevent a routine from consuming the entire program memory page; it merely means that the routine's entry points must be in the lower portion of the page if the routine is called or reached via an instruction that modifies the PCL register. Once code in a routine has been reached, sequential execution of the remainder of the code in that routine can proceed all the way to the end of the page.

To ensure that Baseline routines can be called without placing any further restrictions on the routines' length or location, linker classes can be defined using a modified syntax to specify an entry range. Normally, the option to define a linker class might look something like:
-AMYCLASS=00h-01FFh
which defines a class called MYCLASS with the address range 0 through to 0x1FF. If a routine was linked into this class, the linker could placed it anywhere in this range. But classes can be defined using an additional hyphen-separated address field, for example:
-AMYCLASS=00h-0FFh-01FFh
which tells the linker that when linking any psect into this range, the start of the psect must fall in first specified address range (0 through to 0xFF), but that the remainder of the psect can extend all the way up to the end address, in this case 0x1FF.
The PIC Assembler automatically defines such a linker class that can be used for linking Baseline psects that contain callable code entry points. The class is called ENTRY and you can see this class being used for the psect that holds the increment routine in the example, which is repeated below. Note that this class was not used by the psect that holds the code associated with main. As this example program contains no instructions that call the main label (one instruction jumps to it) this routine can be linked anywhere in program memory and can continue to use the code psect (which is defined by the assembler to use the CODE class).
PSECT entryCode,class=ENTRY,delta=2
increment:
    movwf   loc
    incf    loc,w
    return
After building the example using the command shown in Building the Example, you should see something similar to the following exert taken from the generated map file. Highlighted are the linker options the PIC Assembler driver automatically generates and how the psects used in the example were linked based on those options.
...
  -Mmain.map -E1 --acfsm=1493 -ACODE=00h-01FFhx4 -ASTRCODE=00h-07FFh \
  -AENTRY=00h-0FFh-01FFh,0200h-02FFh-03FFh,0400h-04FFh-05FFh,0600h-06FFh-07FFh \
...
TOTAL           Name                               Link     Load   Length     Space
        CLASS   CODE
                resetVec                              0        0        5         0
                code                                1F6      1F6        A         0
        CLASS   ENTRY
                entryCode                             5        5        3         0
You can see in the linker options at the top that the CODE class consists of four blocks of memory, each being an entire page in size (0x1FF). The ENTRY class consists of four blocks, where each block spans an entire page but with an entry range defined over the first 0xFF bytes of each page.

Down further, you can see that the code psect happened to be linked within the top half of a memory page (at address 0x1F6), but the entryCode psect was linked within one of the entry ranges of the ENTRY class (at address 0x5), as was requested.

The linker will find it more difficult to position psects into a class such as ENTRY due to the additional restrictions imposed by that class, but linking them with these restrictions is necessary for correct program operation. If routines do not have entry points that are called or reached via an instruction that modifies the PCL register, consider placing them in a psect that is linked into the regular CODE class (such as the code psect), to utilize the potentially unused upper portions of program memory pages.