The Linker supports the concept of segments in that the memory space may be partitioned into several segments. The Compiler allows attributing a certain segment name to certain global variables or functions which then are allocated into that segment by the Linker. Where that segment actually lies is determined by an entry in the Linker parameter file.
SegDef = #pragma SegmentType ({SegmentMod} SegmentName | DEFAULT). SegmentType: CODE_SEG|CODE_SECTION| DATA_SEG|DATA_SECTION| CONST_SEG|CONST_SECTION| STRING_SEG|STRING_SECTION SegmentMod: __DIRECT_SEG|__NEAR_SEG|__CODE_SEG| __FAR_SEG|__BIT_SEG|__Y_BASED_SEG| __Z_BASED_SEG|__DPAGE_SEG|__PPAGE_SEG| __EPAGE_SEG|__RPAGE_SEG|__GPAGE_SEG| __PIC_SEG|CompatSegmentMod CompatSegmentMod: DIRECT|NEAR|CODE|FAR|BIT| Y_BASED|Z_BASED|DPAGE|PPAGE| EPAGE|RPAGE|GPAGE|PIC
Because there are two basic types of segments, code and data segments, there are also two pragmas to specify segments:
#pragma CODE_SEG <segment_name>
#pragma DATA_SEG <segment_name>
In addition there are pragmas for constant data and for strings:
#pragma CONST_SEG <segment_name>
#pragma STRING_SEG <segment_name>
All four pragmas are valid until the next pragma of the same kind is encountered.
In the ELF object file format, constants are always put into a constant segment.
Strings are put into the segment STRINGS until a pragma STRING_SEG is specified. After this pragma, all strings are allocated into this constant segment. The linker then treats this segment like any other constant segment.
If no segment is specified, the Compiler assumes two default segments named DEFAULT_ROM (the default code segment) and DEFAULT_RAM (the default data segment). Use the segment name DEFAULT to explicitly make these default segments the current segments:
#pragma CODE_SEG DEFAULT
#pragma DATA_SEG DEFAULT
#pragma CONST_SEG DEFAULT
#pragma STRING_SEG DEFAULT
Segments may also be declared as __SHORT_SEG by inserting the keyword __SHORT_SEG just before the segment name (with the exception of the predefined segment DEFAULT - this segment cannot be qualified with __SHORT_SEG). This makes the Compiler use short (i.e., 8 bits or 16 bits, depending on the Backend) absolute addresses to access global objects, or to call functions. It is the programmer's responsibility to allocate __SHORT_SEG segments in the proper memory area.
The meaning of the other segment modifiers, such as __NEAR_SEG and __FAR_SEG, are backend-specific. Modifiers that are not supported by the backend are ignored.
The segment pragmas also have an effect on static local variables. Static local variables are local variables with the `static' flag set. They are in fact normal global variables but with scope only to the function in which they are defined:
#pragma DATA_SEG MySeg
static char foo(void) {
static char i = 0; /* place this variable into MySeg */
return i++;
}
#pragma DATA_SEG DEFAULT
/* Placed into Segment: */ static int a; /* DEFAULT_RAM(-1) */ static const int c0 = 10; /* DEFAULT_RAM(-1) */ #pragma DATA_SEG MyVarSeg static int b; /* MyVarSeg(0) */ static const int c1 = 11; /* MyVarSeg(0) */ #pragma DATA_SEG DEFAULT static int c; /* DEFAULT_RAM(-1) */ static const int c2 = 12; /* DEFAULT_RAM(-1) */ #pragma DATA_SEG MyVarSeg #pragma CONST_SEG MyConstSeg static int d; /* MyVarSeg(0) */ static const int c3 = 13; /* MyConstSeg(1) */ #pragma DATA_SEG DEFAULT static int e; /* DEFAULT_RAM(-1) */ static const int c4 = 14; /* MyConstSeg(1) */ #pragma CONST_SEG DEFAULT static int f; /* DEFAULT_RAM(-1) */ static const int c5 = 15; /* DEFAULT_RAM(-1) */
/* Placed into Segment: */ static int a; /* DEFAULT_RAM(-1) */ static const int c0 = 10; /* ROM_VAR(-2) */ #pragma DATA_SEG MyVarSeg static int b; /* MyVarSeg(0) */ static const int c1 = 11; /* MyVarSeg(0) */ #pragma DATA_SEG DEFAULT static int c; /* DEFAULT_RAM(-1) */ static const int c2 = 12; /* ROM_VAR(-2) */ #pragma DATA_SEG MyVarSeg #pragma CONST_SEG MyConstSeg static int d; /* MyVarSeg(0) */ static const int c3 = 13; /* MyConstSeg(1) */ #pragma DATA_SEG DEFAULT static int e; /* DEFAULT_RAM(-1) */ static const int c4 = 14; /* MyConstSeg(1) */ #pragma CONST_SEG DEFAULT static int f; /* DEFAULT_RAM(-1) */ static const int c5 = 15; /* ROM_VAR(-2) */