Creating a New Data Segment in Turbo C
PRODUCT : Turbo C NUMBER : 353
VERSION : 2.0
OS : DOS
DATE : September 2, 1992 PAGE : 1/4
TITLE : Creating a New Data Segment
Sometimes people have the need to allow more than one data
segment in their program and they can not change to a HUGE memory
model. This technical information handout explains what is needed
to add an extra data segment to your Turbo C program. You will
need an Assembler to reassemble the start-up code.
The first change you will need to make is to the Turbo C start-up
code. This code defines the segments and their classes as well as
their group. To define a new segment in your program, you will
need to add the definition of the new segment and its class. This
definition must be placed before all of the other segments that
the start-up code defines. See the following listing as an
example of the existing start-up code. The bold text is the new
segment definition that we are adding.
NAME c0
PAGE 60,132
;[]------------------------------------------------------------[]
;| C0.ASM -- Start Up Code |
;| |
;| Turbo-C Run Time Library version 2.0 |
;| |
;| Copyright (c) 1988 by Borland International Inc. |
;| All Rights Reserved. |
;[]------------------------------------------------------------[]
INCLUDE RULES.ASI
_Strict87_ equ false ; emulation skips peculiar details
; Segment and Group declarations
_MYSEG SEGMENT BYTE PUBLIC 'NEWSEG' ; Definition of new
_MYSEG ENDS ; Data Segment
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT PARA PUBLIC 'DATA'
_DATA ENDS
Figure 1: c0.asm
Now that you have changed the start-up code, you will need to
reassemble it for the memory model that you need. The files
RULES.ASI and EMUVARS.ASI will need to be in your current
PRODUCT : Turbo C NUMBER : 353
VERSION : 2.0
OS : DOS
DATE : September 2, 1992 PAGE : 2/4
TITLE : Creating a New Data Segment
directory. The batch file, BUILD-C0.BAT, should be used to
reassemble the start-up code. It takes as a command line
parameter the model name (TINY, SMALL, MEDIUM, COMPACT, LARGE, &
HUGE). Place the modified assembled start-up code in your project
directory.
Now that we have changed the start-up code, we need to compile
the .C file that will be using the data segment. We will use the
following .C module as an example.
char c_buffer1[30000];
char c_buffer2[30000];
Figure 2: module1.c
There are several compiler directives that we will need to pass
to TCC to compile this module for the other segment. Following is
the command line used:
TCC -m? -c -v -zBnewseg -zD_myseg -zGnewgroup -zR_myseg
-zSnewgroup -zTnewseg module1.c
The -m? option is used to specify the memory model for the module
to be compiled in. The ? character should be replaced by the
letter for the model that you wish to use. The -c option tells
the compiler not to invoke the linker. Using -v tells the
compiler to include full debug information. The rest of the
directives specify the names of the segment, class, and group for
both the DATA area and the BSS area. These different options are
discussed in the Turbo C Reference Guide in Appendix C under the
section Segment-Naming Control. Essentially, _myseg is the name
of the segment. This name should match what was placed into the
start-up code. Newseg is the name of the class for the segments
and should correspond to the name in '' in the start-up code. The
newgroup is the name of the group that the segments will be
placed in.
The other module that we are using in our example follows in the
next figure. This module will need to specify the external
variables with the far key word. Please keep in mind that if you
are in one of the near data memory models (TINY,SMALL, and
MEDIUM) that the functions by default only take an offset as a
parameter. The segment used to reference this offset is the data
segment (DS) by default. If you want to use the external data in
PRODUCT : Turbo C NUMBER : 353
VERSION : 2.0
OS : DOS
DATE : September 2, 1992 PAGE : 3/4
TITLE : Creating a New Data Segment
a Turbo C RTL function, you will need to copy the information to
a local variable using the function movedata(). Otherwise, the
COMPACT, LARGE, and HUGE memory models will work fine as long as
you specify that the external variables are far.
#include <dos.h>
#include <stdio.h>
extern char far c_buffer1[30000];
extern char far c_buffer2[30000];
char c_buffer3[30000];
char c_buffer4[30000];
void show_segment(void far *ptr);
main()
{
printf("local proc\n");
printf("extern data ");
show_segment(c_buffer1);
printf("local data ");
show_segment(c_buffer3);
return 0;
}
void show_segment(void far *ptr)
{
printf("segment:%04X\n",FP_SEG(ptr));
}
Figure 3: module2.c
This module can be compiled with a simple command line (again,
remembering to replace the ? with the letter of the memory
model):
TCC -m? -c -v module2.c
Now that each of the modules are compiled, we can link them
together. We are calling TLINK directly because we want to
specify the location of the start-up code. If we pass the .OBJ
files to TCC, it may use the wrong start-up code. The TLINK line
is as follows (replacing the ? with letter of the memory model):
PRODUCT : Turbo C NUMBER : 353
VERSION : 2.0
OS : DOS
DATE : September 2, 1992 PAGE : 4/4
TITLE : Creating a New Data Segment
TLINK /v /c c0? module1 module2, example, example, \tc\lib\c?
The resulting executable program (EXAMPLE.EXE) will display the
segments of the default segment global variables and the external
segment global variables.
DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.
PRODUCT : Turbo C NUMBER : 353
VERSION : 2.0
OS : DOS
DATE : September 2, 1992 PAGE : 1/4
TITLE : Creating a New Data Segment
Figures
Figure 1: c0.asm . . . . . . . . . . . . . . . . . . 1
Figure 2: module1.c . . . . . . . . . . . . . . . . . 2
Figure 3: module2.c . . . . . . . . . . . . . . . . . 3
Comments
Post a Comment