Chapter 3. C Language Features
3.7 Psects
The code generator splits code and data objects into a number of standard "program sections", referred to as psects1. A psect is just a block of something: a block of code; a block of data etc. By having everything inside a psect, all these blocks can be easily recognized and sorted by the linker, even though they have come from different modules.
One of the main jobs of the linker is to group all the psects from the entire project and place these into the available memory for the device.
A psect can be created in assembly code by using the PSECT assembler directive (see
Section 4.3.9.3 “PSECT”). The code generator uses this directive to direct assembly code it produces into the appropriate psect.
3.7.1
Compiler-generated Psects
The code generator places code and data into psects with standard names which are subsequent positioned by the default linker options. The linker does not treat these compiler-generated psect any differently to a psect that has been defined by yourself. Some psects, in particular the data memory psects, use special naming conventions. For example, take the bss psect. The name bss is historical. It holds uninitialized vari- ables. However there may be some uninitialized variables that will need to be located in bank 0 data memory; others may need to be located in bank 1 memory. As these two groups of variables will need to be placed into different memory banks, they will need to be in separate psects so they can be independently controlled by the linker. In addi- tion, the uninitialized variables that are bit variables need to be treated specially so they need their own psect. So there are a number of different psects that all use the same basename, but which have prefixes and suffixes to make them unique. The general form of these psect names is:
[bit]psectBaseNameCLASS[div]
where psectBaseName is the base name of the psect, such as bss.The CLASS is a
TABLE 3-5: INTEGRAL DIVISION
Operand 1 Operand 2 Quotient Remainder
+ + + +
- + - -
+ - - +
If a psect has to be split into two ranges, then the letters l (elle) and h are used as div
to indicate if it is the lower or higher division. A psect would be split if memory in the middle of a bank has been reserved, or is in some what not available to position objects. If an absolute variable is defined and is located anywhere inside a memory range, that range will need to be split to ensure that anything in the psects located there do not overwrite the absolute object. Thus you might see bssBANK0l and bssBANK0h
psects if a split took place.
The contents of these psects are described below, listed by psect base name. 3.7.1.1 PROGRAM SPACE PSECTS
checksum This is a psect that is used to mark the position of a checksum that has been requested using the --CHECKSUM option, see
Section 2.7.19 “--CHECKSUM: Calculate a checksum”. The checksum value is added after the linker has executed so you will not see the contents of this psect in the assembly list file, nor specific information in the map file. Linking this psect at a non-default location will have no effect on where the checksum is stored, although the map file will indicate it located at the new address. Do not change the default linker options relating to this psect.
cinit Used by the C initialization runtime startup code. Code in this psect is output by the code generator along with the generated code for the C program and does not appear in the runtime startup assembly module.
This psect can be linked anywhere in the program memory, provided they does not interfere with the requirements of other psects.
config Used to store the configuration words.
This psect must be stored in a special location in the HEX file. Do not change the default linker options relating to this psect.
eeprom Used to store initial values in the EEPROM memory.
Do not change the default linker options relating to this psect.
idata These psects contain the ROM image of any initialized variables. These psects are copied into the data psects at startup. In this case, the class name is used to describe the class of the corresponding RAM-based data psect. These psects will be stored in program memory, not the data memory space. These psects are implicitly linked to a location that is anywhere within the CODE linker class. The linker options can be changed allowing this psect to be placed at any address in the program memory, provided it does not inter- fere with the requirements of other psects.
idloc Used to store the ID location words.
This psect must be stored in a special location in the HEX file. Do not change the default linker options relating to this psect.
init Used by assembly code in the runtime startup assembly module. The code in this and the cinit define the runtime startup code.
If no interrupt code is defined code from the reset vector may "fall through" into this psect. It is recommended that the default linker options relating to this psect are not changed in case this situation is in effect.
intentry Contains the entry code for the interrupt service routine which is linked to the interrupt vector. This code saves the necessary registers and jumps to
C Language Features
you want to move code when using a bootloader.
jmp_tab Only used for the baseline processors, this is a psect used to store jump addresses and function return values.
Do not change the default linker options relating to this psect.
maintext This psect will contain the assembly code for the main() function. The code for main() is segregated as it contains the program entry point. Do not change the default linker options relating to this psect as the runtime startup code may "fall through" into this psect which requires that it be linked immediately after this code.
powerup Contains executable code for a user-supplied power-up routine. Do not change the default linker options relating to this psect.
reset_vec This psect contains code associated with the reset vector.
Do not change the default linker options relating to this psect as it must be linked to the reset vector location of the target device. See the --CODEOFF- SET option Section 2.7.22 “--CODEOFFSET: Offset Program Code to Address” if you want to move code when using a bootloader.
reset_wrap For baseline PIC devices, this psect contains code which is executed after the device PC has wrapped around to address 0x0 from the oscillator calibration location at the top of program memory.
Do not change the default linker options relating to this psect as it must be linked to the reset vector location of the target device.
strings The strings psect is used for const objects. It also includes all unnamed string literals. This psect is linked into ROM, since the contents do not need to be modified.
This psect can be linked anywhere in the program memory, provided it does not interfere with the requirements of other psects.
textn These psects (where n is a decimal number) contain all other executable code that does not require a special link location.
These psects can be linked anywhere in the program memory, provided they does not interfere with the requirements of other psects.
xxx_text Defines the psect for a function that has been made absolute, i.e. placed at an address. xxx will be the assembly symbol associated with the function. For example if the function rv() is made absolute, code associated with it will appear in the psect called _rv_text.
As these psects are already placed at the address indicated in the C source code, the linker options that position them should not be changed.
3.7.1.2 DATA SPACE PSECTS
nv These psects are used to store persistent variables. They are not cleared or oth- erwise modified at startup.
These psects may be linked anywhere in their targeted memory bank.
bss These psects contain any uninitialized variables.