Important Notice
The pages on this site contain documentation for very old MS-DOS software,
purely for historical purposes.
If you're looking for up-to-date documentation, particularly for programming,
you should not rely on the information found here, as it will be woefully
out of date.
Article Q37030
◄Contents► ◄Index► ◄Back►
─────────────────────────────────────────────────────────────────────────────
◄Knowledge Base Contents► ◄Knowledge Base Index►
Determining Segment Sizes with LINK /MAP in VB for MS-DOS - Q37030
Visual Basic for MS-DOS uses a medium memory model. With this
particular memory model, a program may contain multiple code segments
(up to 64K per module) and one 64K shared data segment (known as
DGROUP). The exceptions to this in Visual Basic for MS-DOS are far
strings, which can be thought of as special string data segments
outside the default data segment, and huge (larger than 64K) dynamic
arrays supported in the far heap. The space that is not used by the
code and DGROUP at run time is left for allocation of dynamic and
huge dynamic arrays.
The LINK .MAP file can be used to determine the size of the code
segment(s) and the static portion of the DGROUP segment, as shown
below. However, the FRE function is easier to use than the LINK .MAP
file for getting information about data allocation.
More Information:
Note that allocating longer variable-length strings may consume more
DGROUP space at run time than is indicated by the initial, static
DGROUP allocation shown in the LINK .MAP file.
Rather than using the LINK .MAP file, a better method of determining
data usage is to invoke the FRE function within a program at run
time. The STACK function returns the amount of dynamic space free for
strings and dynamic arrays in DGROUP. FRE(-1) returns the amount of
space free for dynamic arrays in the far heap.
To generate a link map, use the /MAP switch for the linker (LINK
/MAP). The following link map is generated by linking a module called
DOG.OBJ and is explained further below:
Start Stop Length Name Class
00000H 0003DH 0003EH DOG_CODE BC_CODE
00040H 029A3H 02964H RTCODE CODE
029B0H 02CA0H 002F1H _TEXT CODE
02CA1H 036ABH 00A0BH LMEM CODE
036ACH 036DDH 00032H LOADRTM CODE
036E0H 0374EH 0006FH FOCODE CODE
03750H 03750H 00000H C_ETEXT ENDCODE
03750H 03750H 00000H FDATA FAR_DATA
03750H 03757H 00008H FAR_HDR FAR_MSG
03758H 03D7DH 00626H FAR_MSG FAR_MSG
03D7EH 03D7FH 00002H FAR_PAD FAR_MSG
03D80H 03D80H 00001H FAR_EPAD FAR_MSG
03D90H 03D9FH 00010H NULL BEGDATA
03DA0H 03DA7H 00008H NULL2 BEGDATA
03DB0H 03DB0H 00000H BR_DATA BLANK
03DB0H 03DDFH 00030H BR_SKYS BLANK
03DE0H 03DE0H 00000H COMMON BLANK
03DE0H 03DE5H 00006H BC_DATA BC_VARS
03DE6H 03DE7H 00002H NMALLOC BC_VARS
03DE8H 03DE9H 00002H ENMALLOC BC_VARS
03DEAH 03DEAH 00000H BC_FT BC_SEGS
03DF0H 03DFDH 0000EH BC_CN BC_SEGS
03E00H 03E02H 00003H BC_DS BC_SEGS
03E04H 03E04H 00000H BC_SAB BC_SEGS
03E04H 03E07H 00004H BC_SA BC_SEGS
03E08H 03E0BH 00004H BC_SAE BC_SEGS
03E0CH 03E37H 0002CH CONST DATA
03E38H 03EF0H 000B9H _BSS DATA
03EF2H 04465H 00574H _DATA DATA
04466H 04466H 00000H XIB DATA
04466H 04469H 00004H XI DATA
0446AH 0446AH 00000H XIE DATA
0446AH 0446AH 00000H XECIB DATA
0446AH 0446AH 00000H XECI DATA
0446AH 0446AH 00000H XECIE DATA
0446AH 0446AH 00000H XCB DATA
0446AH 0446DH 00004H XC DATA
0446EH 0446EH 00000H XCE DATA
0446EH 0447BH 0000EH CDATA DATA
0447CH 04489H 0000EH DBDATA DATA
0448AH 0448BH 00002H XIQC DATA
0448CH 0448CH 00000H XIFB DATA
0448CH 0448CH 00000H XIF DATA
0448CH 0448CH 00000H XIFE DATA
0448CH 0448CH 00000H XPB DATA
0448CH 0448CH 00000H XP DATA
0448CH 0448CH 00000H XPE DATA
0448CH 0448CH 00000H XCFB DATA
0448CH 0448CH 00000H XCFCRT DATA
0448CH 0448CH 00000H XCF DATA
0448CH 0448CH 00000H XCFE DATA
0448CH 0448CH 00000H XIFCB DATA
0448CH 0448CH 00000H XIFU DATA
0448CH 0448CH 00000H XIFL DATA
0448CH 0448CH 00000H XIFM DATA
0448CH 0448CH 00000H XIFCE DATA
0448CH 0448CH 00000H BC_DATA BC_DATA
0448CH 0448CH 00000H _BSS BSS
0448CH 0448CH 00000H XOB BSS
0448CH 0448CH 00000H XO BSS
0448CH 0448CH 00000H XOE BSS
0448CH 0448CH 00000H XOFB BSS
0448CH 0448CH 00000H XOF BSS
0448CH 0448CH 00000H XOFE BSS
04490H 0528FH 00E00H STACK STACK
Origin Group
03D9:0 DGROUP
0375:0 FMGROUP
In the above example, a source module called DOG.BAS was compiled and
linked, resulting in a code segment name of DOG_CODE, which is limited
to a maximum of 64K in size (if other compiler limitations are not
exceeded first). DOG_CODE has the class name of BC_CODE. If your code
module is approaching 64K in size, you should break it into SUBprogram
and/or FUNCTION procedures in separate modules that can be compiled
separately and then linked with the main module.
The first seven lines in the above map are the code segments. Each
segment named can be up to 64K in size. Their classes are usually
BC_CODE, CODE, and ENDCODE.
The Origin section at the bottom of the link map tells you the
position where the default data segment (DGROUP) starts, relative to
the start of the .EXE code. The sum of the length of the items in
DGROUP cannot exceed 64K. Items in DGROUP start at 03D9:0 in the above
map [which means offset 0 from the (16-byte) paragraph address 03D9h].
FMGROUP, whose origin is listed at the bottom of the link map as well,
is used for allocation tables and messages relating to far data, such
as variable length strings and dynamic arrays. Space for strings and
arrays in the far heap is not allocated until run time.
Note that the addresses given in the link map are not absolute load
addresses -- instead, they are relative to the start of the code in
the relocatable .EXE file. Only at run time does MS-DOS decide the
absolute address where the .EXE program is loaded in memory. The
VARPTR, VARSEG, SSEG, and SADD functions can then be used within
a Visual Basic for MS-DOS program to determine absolute addresses of
variables and arrays at run time.