6.2.1 Placing Psects into Memory

All code and objects must be placed in a psect (program section). This groups together similar parts of a program and allows you to link those sections using the psect’s name. All psects are allocated memory by the linker, after which, the values for any labels defined in those psects can be determined.

When placing a psect into memory, the linker performs the first of the following operations which matches the situation.
  • If the psect specifies the abs flag, it is placed at address 0 in the memory space indicated by the psect's space flag, or the program memory (default) space if no space has been specified.
  • If a -p linker option references the psect name, the psect is placed at the location specified by that option in the memory space indicated by the psect's space flag, or the program memory (default) space if no space has been specified.
  • If the psect is associated with a linker class, the psect is placed at any free location in the address ranges defined by that class.
  • If the psect specifies a space number, it is placed at a free location in that memory space (Not recommended).
  • The psect is placed in a free location in the program memory (default) space (Not recommended).

Some situations are illegal, for example if you use a -p option to place a psect that also uses the abs flag, then an error will be issued. It is recommended that psects are always linked using the abs flag, using a -p option, or via a linker class (the first three of the above methods). If the linker has to position a psect with no guidance from the user (the last two of the above methods), a warning similar to,(526) psect "wanderer" not specified in -P option (first appears in "not_right.o"), will be emitted.

In most cases, psects can be linked anywhere in a suitable address range that is dictated by the device. For example, most executable code can be placed anywhere in program memory, or at least anywhere in a program memory page. Data objects can usually be placed anywhere in a data bank. In this case, the easiest way to have these psects linked is to associate them with a linker class. If you are using a psect provided by the PIC Assembler, then these are already associated with a suitable linker class and you do not need to specify any linker options to have them correctly linked. In the following example,
PSECT udata_bank1
myVar:
  DS 2
the udata psect has already been associated with the RAM linker class and will be linked anywhere in free memory associated with that class.
If you have created your own psect, you can associate it with any of the existing linker classes provided by the PIC Assembler by using the class flag with the psect definition. In the following example, a psect has been created by the programmer to use instead of udata.
PSECT machData,space=1,class=MDATA
myVar:
  DS 2
This psect uses a new class, MDATA, which will need to be defined by a linker option. To do that, use, for example, the driver option, -Wl,-AMDATA=050h-05fh, which passes the -A linker option directly to the linker and which will associate the specified address range with the MDATA class.

There are, however, times when a psect must be placed at a specific address. The reset vector code is one good example, as are interrupt routines. In this case, you will need to use a -p linker option to place the psect at the desired location. This might be as simple as providing an absolute address, for example using the driver option -Wl,-pInterrupt=08h to place the psect called Interrupt at address 8, but there are more advanced usages of this option.

Check the MPLAB® XC8 PIC Assembler User's Guide for full details concerning the psects and linker classes provided by the PIC Assembler, as well as the linker and driver options mentioned in this section.