[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
Other WarpLink Features
----------------------------------------------------------------------------------------
WarpLink supports several additional features that are useful for
advanced-level programmers. They are: the $$_COM_END internal linker
variable, the $$_EXE_IMAGE_SIZE internal variable, support for custom
overlay manager error handler and overlay file manipulation, and support
for small model code overlaying plus overlay-to-root vectoring.
The $$_COM_END Variable
An age-old problem in the way DOS deals with .COM files is the decision to
leave memory management up to the .COM file. When an .EXE file loads, DOS
allocates to it only the memory it requests automatically. When a .COM file
loads, all available memory is allocated to it. In most situations, the DOS
memory allocation procedure for a .EXE file is preferred over that for a
.COM file because other programs, such as TSRs, can make use of the memory
the .COM file does not need. $$_COM_END is a predefined public symbol that
your program can use for just that purpose.
$$_COM_END is a symbol which represents the linker-computed quantity of
memory that is required by the code and data segments of your program.
Declare it as an EXTRN in your program and use it with INT 21h function 4Ah
to deallocate all except the amount computed, plus whatever stack you need.
$$_COM_END does consume 2 bytes for storage. Therefore a .COM file is two
bytes larger than normal if you declare $$_COM_END as an external. If
$$_COM_END is declared as public, the linker assumes that you wish to use
the variable name for your own purposes and does not treat $$_COM_END as a
special variable.
$$_COM_END automatically adjusts for the Program Segment Prefix (PSP) size
of 256 bytes when computing the required memory.
$$_COM_END depends upon the first object module that contains a class 'CODE'
segment (typically _TEXT) to have the segment listed as the very first
SEGDEF (segment definition) record. Most languages that support .COM files
do this automatically.
----------------------------------[ Example ]------------------------------------
The following an assembly language code fragment shows sample use of the
$$_COM_END variable to reduce the .COM file memory requirements:
EXTRN $$_COM_END:WORD
...
MOV AX, $$_COM_END ; Get program size.
ADD AX, STACKSIZE ; Add stack.
TEST AL,1 ; Check if odd byte-aligned stack
JE @@EVEN ; No: even byte alignment.
INC AX ; Yes it's odd. Bump one.
@@EVEN:
MOV SP, AX ; Initial stack = program size + stack size
SHR AX, 1 ; vide AX by 16.
SHR AX, 1
SHR AX, 1
SHR AX, 1
INC AX ; Round up a paragraph.
MOV BX, AX ; BX = new size of memory block in paragraphs
MOV AH, 4AH ; Resize Memory Block, ES=PSP
INT 21H ; Returns w/ CF=1 on error.
JNC @@NOERROR ; If CF=0, all is well.
MOV AX, 4CH ; Error, exit to DOS
INT 21H ; via function 4Ch.
@@NOERROR:
... ; Success.
The $$_EXE_IMAGE_SIZE Variable
If public symbol $$_EXE_IMAGE_SIZE is declared and the program is linked
without the /c option (therefore producing an .EXE file), WarpLink will
place the doubleword load image size of the file in the $$_EXE_IMAGE_SIZE
symbol. WarpLink will not create the symbol if it is not declared. This
feature is roughly analogous to the $$_COM_END variable created when the
/c option is used. However, it takes into account the more complex
nature of .EXE files.
You must allocate at least four bytes for the variable $$_EXE_IMAGE_SIZE.
Otherwise, WarpLink will write beyond the bounds of the variable, possibly
causing program malfunction. Variable space is not automatically added to
the program by the linker as is done with the $$_COM_END variable.
Using the $$_EXE_IMAGE_SIZE variable provides the capability to easily
determine the end of a program in memory in order to free up excess memory
for DOS or for other programming purposes.
----------------------------------[ Example ]------------------------------------
The following assembly language code fragment shows sample use of the
$$_EXE_IMAGE_SIZE variable to shrink the memory allocated to the program
to its minimum load size:
PUBLIC $$_EXE_IMAGE_SIZE
...
$$_EXE_IMAGE_SIZE DD ?
...
MOV BX,WORD PTR $$_EXE_IMAGE_SIZE ; load image size low word
MOV DX,WORD PTR $$_EXE_IMAGE_SIZE+2 ; load image size high word
ADD BX,15 ; round up to next paragraph
ADC DX,0 ; carry to high word
SHR DX,1 ; convert to paragraph count
RCR BX,1 ; /2
SHR DX,1
RCR BX,1 ; /4
SHR DX,1
RCR BX,1 ; /8
SHR DX,1
RCR BX,1 ; /16, bx holds paragraphs of load image size
ADD BX,10H ; adjust for Program Segment Prefix size
MOV AH,4aH ; resize memory block, es -> PSP
INT 21H
Online resources provided by: http://www.ClipX.Net --- NG 2 HTML conversion by Dave Pearson