Segmentation

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.

Listing: Syntax of the Segment Specification Pragma
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.

Note: You may not declare the DEFAULT code and data segments as __SHORT_SEG.

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

Note: Using the ELF/DWARF object file format (-F1 or -F2 compiler option), the Linker places all constants into the .rodata section by default unless you specify a #pragma CONST_SEG.
Note: Aliases that satisfy the ELF naming convention are available for all segment names. Use CODE_SECTION instead of CODE_SEG. Use DATA_SECTION instead of DATA_SEG. Use CONST_SECTION instead of CONST_SEG. Use STRING_SECTION instead of STRING_SEG. These aliases behave exactly as do the XXX_SEG name versions.
Listing: Example of Segmentation Without the -Cc Compiler Option
                                /* 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) */
Listing: Example of Segmentation with the -Cc Compiler Option
                                /* 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) */