PRODUCT : Turbo C NUMBER : 353 VERSION : 2.0 OS : DOS DATE : October 22, 1993 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 : October 22, 1993 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 : October 22, 1993 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 #include 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 : October 22, 1993 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 : October 22, 1993 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