masm .com(PSP) related trouble

96 views
Skip to first unread message

flekso

unread,
Sep 18, 2002, 2:31:26 PM9/18/02
to
; ensure that we have enough memory
mov ax,cs
add ax,1000h ; require 64K memory
cmp ax,ds:[0002h] ; is end of mem at least 64K above CS?

this is a cutout from a .com file(all segments point at the same direction);
i can't figure out on what basis is this comparison made (i guess it has
something to do with the value in the PSP at the offset 2, but would
appreciate some light shedding on the subject - maybe some links to the PSP
related stuff )

thankyou


FYS

unread,
Sep 18, 2002, 11:16:30 PM9/18/02
to

"flekso" <vend...@hotmail.com> wrote in message
news:amagpu$fcod$1...@as201.hinet.hr...

At offset 0002h in the PSP, DOS places the
"Address of paragraph following the program".

Most of the time, in US MS-DOS versions, this is A000h,
the video memory. I have seen it be different values,
so is not guaranteed to be A000h, but the check above
should be sufficient to check to make sure you have
at least 64k.

However, it is my understanding that if DOS can't allocate
64k for you .com file, it will not load your .com file.

I don't remember if DOS allocates enough memory for
just the .COM image, or the full 64k. Oh, wait, "all
available (conventional) memory is allocated." ?

Time to blow some dust off the old books, huh :)

Ben

--
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Forever Young Software
http://www.cybertrails.com/~fys/index.htm
To reply by email, please remove the zzzzzz's

Batteries not included,
Some assembly required.

Beth

unread,
Sep 26, 2002, 8:54:56 PM9/26/02
to
FYS wrote:
> However, it is my understanding that if DOS can't allocate
> 64k for you .com file, it will not load your .com file.
>
> I don't remember if DOS allocates enough memory for
> just the .COM image, or the full 64k. Oh, wait, "all
> available (conventional) memory is allocated." ?
>
> Time to blow some dust off the old books, huh :)

I don't claim great authority on this but I've just been writing some
.com programs for fun and the behaviour of the assembler (TASM)
strongly suggests that DOS allocates the full 64K...basically, when I
stick uninitialised data after the code, the assembler doesn't
assemble anything into the .com file itself but merely just uses the
space after the memory image, assuming that the memory after it is
allocated for the program's use...but, if I tried to add too much data
to overflow the 64K, it gives a "location counter overflow"
error...although, unlike the other thing that happened, this can't be
completely taken to mean that only 64K is allocated...

Interestingly, the data I wanted to add to the end of the program
needed some random numbers in it and though DOS allocates (at least)
64K for the program, it doesn't appear to initialise the memory in any
way...so, while I was testing the program, I merely used whatever
garbage values happened to be sitting in memory as my "random"
numbers...though, of course, when I finish up the program, I'll
actually put in a proper RNG for this to make sure it is "random"
(rather than crossing my fingers that the uninitialised memory will
just happen to have useful values...as I'm running it within Windows,
I can't be sure quite where these uninitialised values are coming from
that I can depend on it always being full of "interesting" numbers
rather than a series of zeroes or something equally unhelpful...but,
anyway, it's semi-useful to have this while I put the program together
as I can just use these values for now and save adding an RNG until
later, when I can be bothered with that sort of thing ;)...

It _could_ be "all conventional memory" like EXEs are but I haven't
tested that by going beyond 64K...I'd guess one simple way to test it
is to simply allocate some memory with the DOS interrupt for that and
see if it gives you anything useful...actually, I have to say, I've
now been programming Win32 and other things using dynamically
allocated memory that I actually find it a major pain in the butt that
DOS EXEs do all that "allocate all memory" thing...though, if my
memory is serving me correctly (it doesn't always but this half-memory
is coming to mind :), DOS "allocate" interrupt wasn't always
trustworthy if you made lots of allocations and deallocations often
with the earlier versions (or, at least, I'm sure I remember hearing
more than one person complaining about how DOS was messing up their
memory allocations ;) that - being a single-tasking system - the
"cheap and cheerful" solution is "allocate everything
available"..."cheap and cheerful", yes, "sensible and useful", not
really...but there we are...another "hack" in an MS OS to cover up a
miserable implementation...we can't act surprised, can we? hehehe :)

Beth :)


FYS

unread,
Sep 26, 2002, 9:45:39 PM9/26/02
to

"Beth" <BethS...@hotmail.NOSPICEDHAM.com> wrote in message
news:24Ok9.957$2v2.1...@newsfep1-gui.server.ntli.net...

> FYS wrote:
> > However, it is my understanding that if DOS can't allocate
> > 64k for you .com file, it will not load your .com file.
> >
> > I don't remember if DOS allocates enough memory for
> > just the .COM image, or the full 64k. Oh, wait, "all
> > available (conventional) memory is allocated." ?
> >
> > Time to blow some dust off the old books, huh :)

Hi Beth,

I didn't dust off the books, but if my memory serves me
correctly, DOS does allocate the "next-largest" block of
memory for your .com program. However, depending on
allocation stragidy (sp) (it's late :), this could
mean many things.

As one of the first items in your .com program, try allocating
more than about 12k of memory. Depending on the fragmentation
of the memory (MCB's), you will most likely get an "out of memory"
error.

But, this changes with DOS versions (Windows DOS boxes too).

I had a .com file that I was using quite a bit in DOS 5.0 that
allocated memory. As soon as I used Win95's DOS box, **boom**!!!

A small "hack" (smile) for the memory allocation code, and
it seemed to be all better now. :)

It is quite funny though, that DOS will allocate more than 64k
for your .COM program, but without some good hacks, your .com
program can't touch the memory above the 64k line. If you
do make the hacks, you should have just used an .exe anyway,
right.

Good talk'n with ya again,

Ben

P.S. Sorry for the "middle post". I know it isn't good
net'etique (sp) (again, it is late.... :)

Herbert Kleebauer

unread,
Sep 27, 2002, 5:56:25 AM9/27/02
to
FYS wrote:
> "Beth" <BethS...@hotmail.NOSPICEDHAM.com> wrote in message
> news:24Ok9.957$2v2.1...@newsfep1-gui.server.ntli.net...
> > FYS wrote:

> > > However, it is my understanding that if DOS can't allocate
> > > 64k for you .com file, it will not load your .com file.

I have done some testing in DOS6.2. After allocating memory
with int 0x21 fkt 0x31 only 63k memory were free:

----------------------------------------------------------------------------------

Speichertyp Insgesamt = Verwendet + Frei
----------------- ---------- --------- ---------
Konventioneller 639K 576K 63K
Hoher 0K 0K 0K
Reserviert 0K 0K 0K
Erweiterung (XMS) 15.104K 15.104K 0K
----------------- ---------- --------- ---------
Insg. Speicher 15.743K 15.680K 63K

Insg. unter 1 MB 639K 576K 63K

Maximale Größe für ausführbares Programm 63K (64.112 Byte)
Größter freier Block im hohen Speicherblock 0K (0 Byte)

----------------------------------------------------------------------------------

Then I started a com program which displayed the content of CS,
SP and address 2:

CS = 0x9019
SP = 0xfa6e
[2]= 0x9fc0

which means, that only 0xfa70 bytes are available for the
com program. So you always should test at the beginning
of a com program if enough memory is available (if
sp=fffe 64K are available).

> > allocated for the program's use...but, if I tried to add too much data
> > to overflow the 64K, it gives a "location counter overflow"
> > error...

Even if the assembler wouldn't generate an error (use copy to
append data to a com file), dos doesn't load com files greater
then 64k.

> It is quite funny though, that DOS will allocate more than 64k
> for your .COM program, but without some good hacks, your .com
> program can't touch the memory above the 64k line. If you
> do make the hacks, you should have just used an .exe anyway,
> right.

You don't need any "hack" to use the memory above 64k. Just
load ES=DS+0x1000, FS=DS+0x2000 and GS=DS+0x3000 and you can
address 256k without reloading any segment register.

FYS

unread,
Sep 27, 2002, 10:40:01 AM9/27/02
to

"Herbert Kleebauer" <kl...@unibwm.de> wrote in message
news:3D942B49...@unibwm.de...

Hi Herbert,

Thanks for the tests. However, US versions of DOS
are considerably different. :)

> > It is quite funny though, that DOS will allocate more than 64k
> > for your .COM program, but without some good hacks, your .com
> > program can't touch the memory above the 64k line. If you
> > do make the hacks, you should have just used an .exe anyway,
> > right.
>
> You don't need any "hack" to use the memory above 64k. Just
> load ES=DS+0x1000, FS=DS+0x2000 and GS=DS+0x3000 and you can
> address 256k without reloading any segment register.

Indeed. However, I meant if DOS would have loaded more
than 64k of the .COM file and you had initialized data after
the 64k point. :)

Matthias Paul

unread,
Oct 7, 2002, 1:08:08 PM10/7/02
to
On 2002-09-27, Herbert Kleebauer wrote:

> Then I started a com program which displayed the content of CS,
> SP and address 2:
>
> CS = 0x9019
> SP = 0xfa6e
> [2]= 0x9fc0
>
> which means, that only 0xfa70 bytes are available for the
> com program. So you always should test at the beginning
> of a com program if enough memory is available (if
> sp=fffe 64K are available).
>
>>> allocated for the program's use...but, if I tried to add too much
>>> data to overflow the 64K, it gives a "location counter overflow"
>>> error...
>
> Even if the assembler wouldn't generate an error (use copy to
> append data to a com file), dos doesn't load com files greater
> then 64k.

For your convenience a few excerpts from some in-edit files for the
forthcoming RBIL62:

--------D-214B-------------------------------
INT 21 - DOS 2+ - "EXEC" - LOAD AND/OR EXECUTE PROGRAM
AH = 4Bh
AL = type of load
00h load and execute
01h load but do not execute, return debug info
03h load overlay (see #01591)
04h load and execute in background (European MS-DOS 4.0
only) "Exec & Go" (see also AH=80h)
DS:DX -> ASCIZ program name (must include extension)
ES:BX -> parameter block (see #01590,#01591,#01592)
CX = mode (subfunction 04h only)
0000h child placed in zombie mode after termination
0001h child's return code discarded on termination
Return: CF clear if successful
AX,BX,DX destroyed
if subfunction 01h, process ID set to new program's PSP;
get with INT 21/AH=62h
(Novell DOS 7+) if subfunction 03h, AX=SETVERed version
or 0000h.
CF set on error
AX = error code (01h,02h,05h,08h,0Ah,0Bh)
(see #01680 at AH=59h)
Notes: DOS 2.x destroys all registers, including SS:SP; one possible
work-around is to save the SS:SP stack pointer in a local
variable before calling INT 21h/AH=4Bh and restore the old
SS:SP afterwards (the CLI/STI in order to work around a bug
in early 8088 CPUs):
...
INT 21h ; INT 21h/4Bh
CLI
MOV SS,CS:stack_seg
MOV SP,CS:stack_ofs
STI
PUSH CS
POP DS
...
newer DOS versions (like 5 or 6) still destroy AX, BX, DX
because internally they call functions to deal with files,
allocating memory, etc. which set values to be returned in
the registers to the caller.
under ROM-based DOS, if no disk path characters (colons or
slashes) are included in the program name, the name is
searched for in the ROM module headers (see #01595) before
searching on disk
for functions 00h and 01h, the calling process must ensure that
there is enough unallocated memory available; if necessary,
by releasing memory with AH=49h or AH=4Ah
for function 01h, the AX value to be passed to the child
program is put on top of the child's stack; the info returned
by function 01h is used by debuggers.
function 01h was undocumented prior to the release of DOS 5.0.
function 02h is not implemented in any known DOS issues so
far - its originally intended purpose is not currently
known.
function 03h is used by the DOS BIOS to load device drivers.
for function 03h, DOS assumes that the overlay is being loaded
into memory allocated by the caller.
for function 03h, the MS-DOS/PC DOS (at least 6.x+) kernel
checks a special internal flag which indicates, if the
system is still in SYSINIT. Under these DOS versions DEVICE=
statements are reordered and always get executed prior to
INSTALL= statements, hence this flag indicates that the
INT 21h/AH=4Bh overlay call must have been issued
by the DOS BIOS in order to load a device driver.
Since device drivers don't have a PSP to store the SETVERed
version in there, the kernel patches the corresponding
SETVERed version for the device driver into a special PSP
data structure stored in the DOS BIOS init??? code. This
allows to retrieve SETVERed versions even for device drivers
at least until the next call to INT 21h/AX=4B03h was
issued. This usually allows to fake DOS versions during a
device driver's initialization (where DOS version checks
usually occur), but is not completely reliable and may
return invalid faked versions afterwards.
for function 03h, DR DOS "Panther", Novell DOS 7+ (still DR-DOS
7.05) undocumentedly return AX = SETVERed version or zero for
similar purposes, but the DOS BIOS does not currently make
use of this info. This is not supported by NetWare PalmDOS
and earlier versions of DR DOS.
(Just in case future issues would have to drop this special
case for compatibility with DOS, it is recommended to call
this function with a magic BP=0EDCh which would then still
return the special AX return code. It might be possible to
store the SETVERed version in two of the unused BYTEs of
the device driver's MCB header in the future.)
under OS/2 the FSFILTER.SYS program takes over INT 21h/AH=4Bh
and does not return a proper AX value, hence Novell DOS 7+
(since 1994-05-24) directly pokes the version number into
the PSP instead of relying on the AX return.
some versions (such as DR DOS 6.0) check the parameters and
parameter block and return an error if an invalid value
(such as an offset of FFFFh) is found
under RxDOS 6.0-7.1.6, subfunction 03h has been extended to not
require a preallocated block of memory. If the address of the
overlay block is zero, the function will predetermine the
program size based on its type, that is, whether it is a
.COM or .EXE file.
background programs under European MS-DOS 4.0 must use the new
executable format
this function ignores the filename extension, instead checking
the first two bytes of the file to determine whether there
is a valid .EXE header (see #01594); if not, the file is
assumed to be in .COM format. If present, the file may be
in any of several formats which are extensions of the
original .EXE format (see #01593)
the .COM executable format was not intended to support larger
than 64 Kb memory images, however, some DOS issues can deal
with larger files to a varying degree.
MS-DOS 6.0 will read only the first 64 Kb-PSP of the image in
case it would be larger, the stack pointer will be set to
SS:FFFEh.
DOS-C (1996) seems to load up to 64 Kb of data with unknown
consequences for the PSP (wrap around???) and the stack at
SS:FFFEh-something???
RxDOS 6.0-7.1.6 will load .COM-format executables into memory
even when they are larger than 64 Kb, but the stack pointer
will be created at the end of the first segment, and thus
will overwrite parts of the image if this has not been taken
into account.
PTS-DOS 6.51 and S/DOS 1.1 will completely discard
.COM-format executables larger than FEFFh bytes (64 Kb-PSP)
file size.
.COM-format executables begin running with the following
register values:
AL = 00h if first FCB has no or a valid drive letter,
FFh if no valid drive letter
AH = 00h if second FCB has no or a valid drive letter,
FFh if no valid drive letter
CS,DS,ES,SS = PSP segment
IP = load offset (0100h)
SP = offset of last WORD available in first 64K segment
(that is FFFEh) or the maximum size of memory
available in the block the program is loaded into
for both, the program plus at least 256 bytes
stack (which may change with loadhigh region
support options), whatever is smaller, or 00FEh
on very early DOS issues (DOS v1???).
Notes: officially, BX,CX,DX,SI,DI,BP,Flags, as well as
the high register words on 386+ CPUs are
undefined and should not be relied upon in
programs
AL and AH are always 00h under both, DESQview
and RxDOS 6.0-7.1.6, while under DOS-C they
are always FFh (probably also under FreeDOS -
subject to change).
AX appears to be zero under MS-DOS/PC DOS
DEBUG, but the DR-DOS 7.xx DEBUG.EXE sets
up the AH and AL values according to the
results of the first and second FCB tests,
however, the results are different from the
values for INT 21h/AH=4Bh (00h for no valid
or default drive letter, 01h..1Ah for A:..Z:,
many other chars x: appear to be returned
with either +B0h, +40h, or +20h added to
the letter, for example 0:..9: resulting
in D0h..D9h???).
BX:CX holds the size of the program under RxDOS
6.0-7.1.6, similar to what usually happens
under other DOSes when loading a program in
DEBUG.EXE.
Both registers are set to 0000h under DOS-C
(1996) and the later FreeDOS (BETA 7).
DX,SI,DI,BP are all set to 0000h under RxDOS
6.0-7.1.6, DOS-C, and FreeDOS, but not under
operating sytems of the MS-DOS/PC DOS or
DR-DOS families. These registers are set
to 0000h under DEBUG.EXE.
the Flags are set to 0000h under RxDOS
6.0-7.1.6, DOS-C, and FreeDOS, but not
under the other DOSes.
the stack holds a WORD of 0000h so that the
program can be terminated with a simple RETN,
which falls into the CP/M-style exit point,
the INT 20h at offset +00h in the PSP, similar
to just jumping to offset +00h or performing
a INT 20h directly.
apparently, DR DOS before 1988-08-18 tried to
reserve 4000h bytes of stack for .COM
programs, not just the usual 100h. This was
changed for ACCPAC.
BUGs: some badly written utilities seem to rely on the
D-Flag being cleared on startup, a condition
that must not necessarily be true, so noone
should rely on this.
some obscure "smallest program contests"
exercises rely on the high byte of BP equal
to 09xxh on entry, a condition that accidently
exists in several vesions of MS-DOS
COMMAND.COM, including MS-DOS 5.0, Windows95
OSR 2.x DOS box, Windows 98SE DOS box,
Windows 2000 DOS box, but for example not
in other DOSes like DR-DOS, where the value
varies on circumstances. No program should
rely on such random sideeffects of a
particular implementation.
old-format .EXE executables begin running with the following
register values:
AL = 00h if first FCB has no or a valid drive letter,
FFh if no valid drive letter
AH = 00h if second FCB has no or a valid drive letter,
FFh if no valid drive letter
DS,ES = PSP segment
SS:SP as defined in .EXE header
CS:IP points to entry point into program
Notes: .EXE-format programs without a stack segment are
treated differently depending on version;
under DOS 5.0+ if the obtained memory block
is larger or equal to 64 Kb the stack pointer
will not be touched, otherwise the pointer
will be initialized similar as for .COM-
format programs, that is, as long as the
program's memory requirements are less than
64 Kb 256 bytes stack will be added if
possible, otherwise SP is placed at the top
of the 64 Kb at FFFEh.
officially, BX,CX,DX,SI,DI,BP,Flags, as well as
the high register words on 386+ CPUs are
undefined and should not be relied upon in
programs
AL and AH are always 00h under both, DESQview
and RxDOS 6.0-7.1.6, while under DOS-C they
are always FFh (probably also under FreeDOS -
subject to change).
AX appears to be zero under MS-DOS/PC DOS
DEBUG, but the DR-DOS 7.xx DEBUG.EXE sets
up the AH and AL values according to the
results of the first and second FCB
tests, however, the results are different
from the values for INT 21h/AH=4Bh (00h for
no valid or default drive letter, 01h..1Ah
for A:..Z:, many other chars x: appear to
be returned with either +B0h, +40h, or
+20h added to the letter, for example 0:..9:
resulting in D0h..D9h???).
BX:CX holds the size of the program under RxDOS
6.0-7.1.6, similar to what usually happens
under other DOSes when loading a program in
DEBUG.EXE. Both registers are normally set
to 0000h under DOS-C and FreeDOS (BETA 7),
but if compiled as IPL, BX holds the boot
drive and CX the number of floppies.
DX,SI,DI,BP are all set to 0000h under RxDOS
6.0-7.1.6, DOS-C and FreeDOS but not under
operating systems of the MS-DOS/PC DOS or
DR-DOS families. These registers are set
to 0000h under DEBUG.EXE.
the Flags are set to 0000h under RxDOS
6.0-7.1.6, DOS-C, and FreeDOS, but not
under the other DOSes.
the stack can be pre-initialized.
BUG: some badly written utilities seem to rely on the
D-Flag being cleared on startup, a condition
that must not necessarily be true, so noone
should rely on this.
new executables begin running with the following register
values
AX = environment segment
BX = offset of command tail in environment segment
CX = size of automatic data segment (0000h = 64K)
ES,BP = 0000h
DS = automatic data segment
SS:SP = initial stack
the command tail corresponds to an old executable's PSP:0081h
and following, except that the 0Dh is turned into a NUL
(00h); new format executables have no PSP
under the FlashTek X-32 DOS extender, only function 00h is
supported and the pointers are passed in DS:EDX and ES:EBX
DR Concurrent DOS 386 (since 1988-07-08) will load EXEPACKed
programs above the 64K mark, that is, outside "lowest
memory", by extending the memory block containing the
program's environment (even larger than 32 Kb???).
DR DOS 5.0+ always loads .EXE-format programs with no fixups,
and (since 1990-05-25) also .COM-format programs compressed
with SpaceMaker - and therefore starting with 9Ch 55h
(PUSHF/PUSH BP) - above the 64K mark to avoid the EXEPACK
wrap around bug. It does this by extending the memory block
containing the program's environment, since 1989-12-14 it
will even allocate multiple fillers when necessary.
This environment expansion code is disabled if the name
of the parent program as stored in the MCB is "WIN" to
improve performance when WIN.COM starts KERNEL.EXE
(0 relocation items).
DR DOS 3.41 and 5.0 check for a valid filename before testing
the subfunction number, so the otherwise invalid subfunction
02h will only return error code 01h if the given filename
actually exists; otherwise, errors 02h, 03h, or 05h are
returned. This was corrected on 1990-10-02 for DR DOS 6.0+,
which range checks the subfunction before checking the
filename now.
the MS-DOS/PC DOS 5.0+??? kernel scans for a variety of code
sequences in .EXE format executables and applies patches
for various versions of EXEPACKed files in order to let
them run in lowest memory (when DOS is in the HMA), that
is, a load segment < 64 Kb. Otherwise they would display
"Packed file corrupt".
The code checks that the code's entry point ("IP") is not
< 0002h (it was 0012h in the observed files) and then reads
the WORD immediately preceeding the entry point (that is,
0010h here). If this WORD reads 5242h ("RB"), the file is
assumed to be EXEPACKed. The code then looks for one of
several combinations of code sequences at offsets from
this "RB" signature.
the MS-DOS 5.0+??? kernel scans for an unknown class of .COM
executables. If their signatures are found in the file, the
A20 countdown variable at offset 18h in the disk buffer info
table (see Table "DOS 5.0-6.0 disk buffer info") will
be set to 10, which will cause A20 to be disabled after
INT 21h calls for this count of INT 21h calls to follow.
Presumably this class of programs requires A20 to be disabled
for some time after it begins execution. (Similar actions
occur on entry into INT 21h/AH=25h and AH=49h.)
BUGS: DOS 2.00 assumes that DS points at the current program's PSP
Load Overlay (subfunction 03h) loads up to 512 bytes too many
if the file contains additional data after the actual overlay
Load but Do Not Execute (subfunction 01h) is reported to
corrupt the top word of the caller's stack if the loaded
module terminates with INT 21/AH=4Ch in some versions of
MS-DOS, including v5.00.
according to Rational Systems, MS-DOS/PC DOS 5.0+ searches
executables for a number of opcode sequences which indicate
various older issues of the Rational DOS Extender before
version 3.95; if found, the kernel will apply assorted
patches for 286 and 386 CPUs to the loaded program image:
the 286 patch fixes the trashing of the CX register in a
certain loop; it will by applied by DOS 5.0+ on 286 CPUs
only when the kernel is relocated into the HMA. The patch
itself resides statically in the DOS data segment.
on 386er CPUs, DOS 6.0+ overwrites parts of the Extender's
unused code for 286 CPUs or the code dealing with
NEC 98xx's with several version dependent patches fixing
the trashing of the high word of EAX (if not DPMI or VCPI)
and the high words of EAX,EBX,ECX,EDX,ESI (if VCPI),
but forgets to fix the trashing of the high word of ESP and
the corruption of the FS and GS registers, which can occur
during interrupt processing.
Lotus 1-2-3 version 3.x+??? is one of the applications using
buggy versions of the Rational System DOS extender.
SeeAlso: AX=4B05h,AH=4Ch,AH=4Dh,AH=64h/BX=0025h,AH=8Ah,INT 2E,
INT 60/DI=0604h

Format of EXEC parameter block for AL=00h,01h,04h:
Offset Size Description (Table 01590)
00h WORD segment of environment to copy for child process (copy
caller's environment if 0000h)
02h DWORD pointer to command tail to be copied into child's PSP
at 80h (See Table "command tail" at INT 21h/AH=26h)
06h DWORD pointer to first FCB to be copied into child's PSP
at 5Ch
0Ah DWORD pointer to second FCB to be copied into child's PSP
at 6Ch
0Eh DWORD (AL=01h) will hold subprogram's initial SS:SP on return
12h DWORD (AL=01h) will hold entry point (CS:IP) on return
Notes: PTS-DOS 6.51 will allocate the environment above the program
when the INSTALL[HIGH] /E load option was used (SeeAlso:
INT 21h/AH=58h).
early versions of DR Concurrent DOS and DOS Plus did not cope
with an environment value of zero; this was fixed on
1988-06-02 for the [D]CONFIG.SYS INSTALL= directive,
apparently introduced around this date in Concurrent DOS???
(This directive showed up in the single-user series not
before a year later with DR DOS 3.41+???)
if the environment segment supplied is zero and the caller also
has a zero environment, DOS will not allocate an environment
at all.
DR DOS 5.0+ (since 1990-04-10), RxDOS 6.0+ (at least since
1994-06-06), and DOS-C (1996) are known to handle this
special case as well.
MS-DOS/PC DOS/DR-DOS, and DOS-C (1996) verifies that the actual
environment is at most 32768 bytes long and is
zero-terminated, if it is not, the kernel will bail out.
in order to reduce memory fragmentation and save memory, future
issues of DR-DOS (post 7.05) may possibly add new load
options like

[HI]INSTALL|INSTALL[HIGH] and LH|LOADHIGH|HILOAD
[/D[:d[:]]] [/E] [/L...] [/S] [/Z] = d:\path\prg.com params,

where:

/D starts the program from a temporary SUBSTed drive
(default B:)
/E places the environment above the program instead
of below
/Z creates a zero-environment (similar to DESQview's
feature)

RxDOS 6.0 is known to handle the case of a zero command tail
pointer, in which case it will not copy a command tail into
the PSP.
DOS-C (1996) will truncate the command tail copied into the PSP
so it never exceeds 127 characters and it will always
terminate it with a 0Dh (CR).
SeeAlso: #01591,#01592

If you find errors or omissions, please let me know.

Greetings,

Matthias

--
<mailto:Matthi...@post.rwth-aachen.de>; <mailto:mp...@drdos.org>
http://www.uni-bonn.de/~uzs180/mpdokeng.html; http://mpaul.drdos.org

"Programs are poems for computers."


Herbert Kleebauer

unread,
Oct 8, 2002, 3:02:11 AM10/8/02
to
Matthias Paul wrote:

> For your convenience a few excerpts from some in-edit files for the
> forthcoming RBIL62:
>
> --------D-214B-------------------------------
> INT 21 - DOS 2+ - "EXEC" - LOAD AND/OR EXECUTE PROGRAM
> AH = 4Bh

> the .COM executable format was not intended to support larger


> than 64 Kb memory images, however, some DOS issues can deal
> with larger files to a varying degree.
> MS-DOS 6.0 will read only the first 64 Kb-PSP of the image in
> case it would be larger, the stack pointer will be set to
> SS:FFFEh.

Are you sure? At least in DOS 6.20 (German Version) command.com
will not execute a com program greater 64K. And I think command.com
also just uses INT21 AH=4B.

Matthias Paul

unread,
Oct 9, 2002, 6:32:06 AM10/9/02
to
On 2002-10-08, Herbert Kleebauer wrote:

>> For your convenience a few excerpts from some in-edit files for
>> the forthcoming RBIL62:
>>
>> --------D-214B-------------------------------
>> INT 21 - DOS 2+ - "EXEC" - LOAD AND/OR EXECUTE PROGRAM
>> AH = 4Bh

| [...]


>> the .COM executable format was not intended to support larger
>> than 64 Kb memory images, however, some DOS issues can deal
>> with larger files to a varying degree.
>> MS-DOS 6.0 will read only the first 64 Kb-PSP of the image
>> in case it would be larger, the stack pointer will be set
>> to SS:FFFEh.

???


| DOS-C (1996) seems to load up to 64 Kb of data with unknown
| consequences for the PSP (wrap around???) and the stack at
| SS:FFFEh-something???
| RxDOS 6.0-7.1.6 will load .COM-format executables into

| memory even when they are larger than 64 Kb, but the stack
| pointer will be created at the end of the first segment,


| and thus will overwrite parts of the image if this has not
| been taken into account.
| PTS-DOS 6.51 and S/DOS 1.1 will completely discard
| .COM-format executables larger than FEFFh bytes (64 Kb-PSP)
| file size.

| [...]


>
> Are you sure? At least in DOS 6.20 (German Version) command.com
> will not execute a com program greater 64K. And I think command.com
> also just uses INT21 AH=4B.

Thanks for the reply. Of course, the shell does use this function.
I just tried it under MS-DOS 7.10 (from Windows 98 SE) and DR-DOS 7.03:

Under MS-DOS 7.10, the prepared .COM file is rejected due to the
API function returning an error (similar to your own observation),
whilst under DR-DOS 7.03 it is accepted. The error messages were
different, but the results were the same under both, COMMAND.COM
and 4DOS.COM.

Unfortunately, I don't have MS-DOS 6.0 and 6.22 here right now
to run cross-checks, but clearly, this needs some more detailed
investigation to track this down. Let's move this into the
news:alt.msdos.programmer group, where I posted a similar
answer under the subject "Run a COM file" on 2002-10-07;
I think it's more on-topic there.

My dumb test file today was derived from a true .COM style file
(not a "MZ" or "ZM" .EXE style file renamed to .COM) and I just used:

COPY /B true.com+true.com huge.com

to create a file image larger than 64 Kb. (The resulting file was
128.666 bytes in size, in case the exact size makes a difference,
somehow.)

Anyone else?

Greeetings,

Joe Fischer

unread,
Oct 9, 2002, 3:53:06 PM10/9/02
to
In alt.msdos.programmer

Matthias Paul <Matthi...@post.rwth-aachen.de> wrote:
: On 2002-10-08, Herbert Kleebauer wrote:
: My dumb test file today was derived from a true .COM style file


: (not a "MZ" or "ZM" .EXE style file renamed to .COM) and I just used:
:
: COPY /B true.com+true.com huge.com
:
: to create a file image larger than 64 Kb. (The resulting file was
: 128.666 bytes in size, in case the exact size makes a difference,
: somehow.)
:
: Anyone else?

The specification for a MSDOS .COM file states
that Stack, Code and Data segments begin at the same
address, with the first FF bytes containing file info,
and the code starting at 0100 HEX.

This fact restricts the size to one segment,
or 64 k.
There is no minimum size for a .COM file as
long as there is an INT 20H (terminate program)
and an end of file marker.

A .COM file is not restricted to the DOS
Interrupt 21H, but programs that use only that
interrupt will run without modification on most
any MSDOS machine. (There were many machines
that ran MSDOS during the 1980's, but perhaps
not so many now).

By using only INT 21H, text plane video
will work on any machine that runs MSDOS even
if the video memory resides at a different
address than C000 or C800 Hex in the 1st meg.
Some early MSDOS machines used IBM
format floppies, some did not.

Joe Fischer

--
3

Dufflepod

unread,
Oct 9, 2002, 8:09:38 PM10/9/02
to
On 9 Oct 2002 15:53:06 -0400, Joe Fischer <grav...@shell1.iglou.com>
wrote:

>In alt.msdos.programmer
>
>Matthias Paul <Matthi...@post.rwth-aachen.de> wrote:
> There is no minimum size for a .COM file as
>long as there is an INT 20H (terminate program)
>and an end of file marker.
>


Nonsense!

In the first place, you don't need an INT 20h at the end of a .COM
programme, a simple near return will do. Which works because DOS
pushes zero onto the stack before passing control to the COM prog @
0100h, so when it does a return, this loads the IP with 0000, which
conviently points to the 'INT 20h' at offset 0 in the PSP.

This also means, that the smallest size of a COM programme is 1 byte,
namely, C3h, a near return.

As for an end of file marker for a .COM prog, what are you talking
about?! The filesize is stored in the directory entry for the prog.


Dufflepod.

David A. Caabeiro

unread,
Oct 11, 2002, 9:22:09 AM10/11/02
to
> This fact restricts the size to one segment,
> or 64 k.

In fact, this restricts com size to 64Kb - 256 bytes
for the PSP...

Regards,
David.

Norm Dresner

unread,
Oct 12, 2002, 8:14:52 PM10/12/02
to
David A. Caabeiro <nos...@yahoo.com.ar> wrote in message
news:ao6qq6$jjv9u$1...@ID-84876.news.dfncis.de...
Once a .COM program has started running there's nothing that can stop
it from using different addresses in the various segment registers so that
a .COM program can -- and some do -- use all of the available memory.

Norm

Joe Fischer

unread,
Oct 13, 2002, 4:20:44 AM10/13/02
to
In alt.msdos.programmer Dufflepod <Duff...@hotmail.com> wrote:
: On 9 Oct 2002 15:53:06 -0400, Joe Fischer <grav...@shell1.iglou.com>
: wrote:
:
: Nonsense!

:
: In the first place, you don't need an INT 20h at the end of a .COM
: programme, a simple near return will do. Which works because DOS
: pushes zero onto the stack before passing control to the COM prog @
: 0100h, so when it does a return, this loads the IP with 0000, which
: conviently points to the 'INT 20h' at offset 0 in the PSP.
:
: This also means, that the smallest size of a COM programme is 1 byte,
: namely, C3h, a near return.

The reason I mentioned it was to compare the
minimum size of an .EXE file, which needs an extensive
header, but I didn't get around to saying that.

The fact that there is an INT 20 at the beginning
of the Program Segment Prefix is just trivia, because
the PSP is not part of the program.

: As for an end of file marker for a .COM prog, what are you talking


: about?! The filesize is stored in the directory entry for the prog.
: Dufflepod.

I like to add an EOF marker to all DOS
files so they can be treated as certain DOS files,
which should have an EOF marker, even if only
to be consistent.

Joe Fischer

--
3

Joe Fischer

unread,
Oct 13, 2002, 4:23:25 AM10/13/02
to
In alt.msdos.programmer

David A. Caabeiro <nos...@yahoo.com.ar> wrote:
:> This fact restricts the size to one segment,


:> or 64 k.
:
: In fact, this restricts com size to 64Kb - 256 bytes
: for the PSP...

Right, 65,536 bytes minus the 256 byte PSP which
only exists in core memory.

Joe Fischer

--
3

David A. Caabeiro

unread,
Oct 13, 2002, 3:22:28 PM10/13/02
to
> > In fact, this restricts com size to 64Kb - 256 bytes
> > for the PSP...
> >
> > Regards,
> > David.
> >
> Once a .COM program has started running there's nothing that can stop
> it from using different addresses in the various segment registers so that
> a .COM program can -- and some do -- use all of the available memory.

The OP was refering to COM image size, not its ability to allocate
extra memory.

Regards,
David.

Norm Dresner

unread,
Oct 13, 2002, 6:41:13 PM10/13/02
to
David A. Caabeiro <nos...@yahoo.com.ar> wrote in message
news:aoch49$lcoh6$1...@ID-84876.news.dfncis.de...
That's not clear from where I jumped into the middle of the thread.
Sorry.

Norm

Dufflepod

unread,
Oct 18, 2002, 8:10:59 PM10/18/02
to
On 13 Oct 2002 04:20:44 -0400, Joe Fischer <grav...@shell1.iglou.com>
wrote:

[ S N I P ]

>
>: As for an end of file marker for a .COM prog, what are you talking
>: about?! The filesize is stored in the directory entry for the prog.
>: Dufflepod.
>
> I like to add an EOF marker to all DOS
>files so they can be treated as certain DOS files,
>which should have an EOF marker, even if only
>to be consistent.
>

This is still bollocks. In text mode, typing or copying a file in
cooked, as opposed to raw mode, will stopp at the *text* EOF byte,
which is 1A hex.

But, in a binary file, like a COM, or EXE, or any other non-text file,
a byte value 1Ah can legitimately appear anywhere, and not signify
end-of-file. It can just be the decimal value 26, or the 1st byte of
an SBB opcode, or pretty much any other data value. But and EOF at the
end of a file...... Nah.

Once again - there's no such thing as an EOF marker at the end of a
DOS binary file. So you're not being consistant at all, you're just
plain wrong. Be told.

Dufflepod.

Reply all
Reply to author
Forward
0 new messages