The Linker supports the concept of segments in that you may partition the memory space into several segments. The Compiler allows attributing a certain segment name to certain global variables or functions which the Linker then allocates into that segment. An entry in the Linker parameter file determines where that segment actually lies.
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|__LINEAR_SEG|CompatSegmentMod CompatSegmentMod=DIRECT|NEAR|CODE|FAR|BIT|Y_BASED|Z_BASED| DPAGE|PPAGE|EPAGE|RPAGE|GPAGE|PIC
The two basic types of segments, code and data segments, require two pragmas for segment specification:
In addition there are pragmas for constant data and for strings:
All four pragmas remain valid until the next pragma of the same kind is encountered.
In the HIWARE object file format, the Linker puts constants into DATA_SEG unless you specify a CONST_SEG. In the ELF Object file format, the Linker always puts constants into a constant segment.
The Linker puts strings into the STRINGS segment until you specify a STRING_SEG pragma. After this pragma, the Linker allocates all strings into this constant segment. The linker then treats this segment like any other constant segment.
If you do not specify a segment, 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
You may also declare segments as __SHORT_SEG by inserting the keyword __SHORT_SEG just before the segment name. This makes the Compiler use short absolute addresses (8 bits or 16 bits, depending on the Backend) 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 backend specifies the meaning of the other segment modifiers, such as __NEAR_SEG and __FAR_SEG. The backend ignores unsupported modifiers. Refer to HC(S)08 Backend for information about modifier support.
The segment pragmas also affect static local variables. Static local variables are local variables with the static flag set. They are in fact normal global variables but with scope limited to the function in which they are defined:
#pragma DATA_SEG MySeg
static char myfun(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) */