[comp.sys.ibm.pc] DOS memory allocation

jwbirdsa@phoenix.Princeton.EDU (James Webster Birdsall) (05/10/89)

   I need to be able to permanently allocate memory from a
memory-resident piece of code WHILE running an application without
fragmenting the memory when the application exits. It occurred to me
that an easy way to do this would to be allocate memory from the top
down instead of bottom up, as usual. Can DOS be persuaded to do this
in an elegant manner? If not, can it be kluged like so: if we need X
kbytes and there are N left, allocate a block of N-X, then the block of
X, then deallocate the first? Or would allocating from the top down also
count as fragmenting and cause DOS to vaporize?
   Assuming it can't be done, could I hook the exit interrupt and, when
it is called, call it and then somehow paw through the allocation chain
to find holes?

   Another random thought: I seem to recall hearing that DOS allocates
all available memory to .COM programs. Is this true? If it is, does it
spell certain doom for my plans?

   Yet another random thought: saw somebody praising the program MAPMEM
recently. I have version 2.1; I will admit that it's a nice program, but
sometimes using it causes some of my other memory mappers to scream that
the memory allocation chain has been corrupted! Don't know whether it's
MAPMEM's fault or not.

   Anyway, thanx for any thoughts on the questions above...

-- 
James W. Birdsall  jwbirdsa@phoenix.Princeton.EDU  jwbirdsa@pucc.BITNET
   ...allegra!princeton!phoenix!jwbirdsa   Compu$erve: 71261,1731
"For it is the doom of men that they forget." -- Merlin

johnm@spudge.UUCP (John Munsch) (05/13/89)

In article <8261@phoenix.Princeton.EDU> jwbirdsa@phoenix.Princeton.EDU (James Webster Birdsall) writes:
>                                                   It occurred to me
>that an easy way to do this would to be allocate memory from the top
>down instead of bottom up, as usual. Can DOS be persuaded to do this
>in an elegant manner?

I'm sure you'll get tons of responses, but just in case...

DOS versions past 3.0 have the INT 21h function call 58h which sets the DOS
memory allocation strategy.  One of the available options for this is to
allocate from the top down.  Consult a DOS technical manual for details on
the parameters of the function call.

John Munsch
Son of "Sam I Am"

vrh@mhres.mh.nl (Michael Verhey) (05/17/89)

In article <670@spudge.UUCP>, johnm@spudge.UUCP (John Munsch) writes:
> In article <8261@phoenix.Princeton.EDU> jwbirdsa@phoenix.Princeton.EDU (James Webster Birdsall) writes:
> >                                                   It occurred to me
> >that an easy way to do this would to be allocate memory from the top
> >down instead of bottom up, as usual. Can DOS be persuaded to do this
> >in an elegant manner?
> 
> I'm sure you'll get tons of responses, but just in case...
> 
> DOS versions past 3.0 have the INT 21h function call 58h which sets the DOS
> memory allocation strategy.  One of the available options for this is to
> allocate from the top down.  Consult a DOS technical manual for details on
> the parameters of the function call.

You can use int 21h, function 58h as follows:

Calling registers:	AH = 58h
			AL = 00h, get strategy code
			     01h, set strategy code
			BX = Strategy code if setting it
			     00h, first fit (default)
			     01h, best fit
			     02h, last fit

Return registers:	Carry flag if cleared successful
			AX = Strategy code (if getting it)

			Carry flag set if error
			AX = Error code
			     01h, invalid function (file sharing)

By the way, I can highly recommend the book "DOS Programmer's Reference" by
Terry R. Dettmann (Que Corporation). It describes every BIOS and DOS call
available till DOS V3.3.

Good luck,
Michael
-- 
Michael Verheij (using Netnews)		Multihouse B.V., the Netherlands
USENET: vrh@mh.nl via European backbone (mcvax).
UUCP:   ..!mcvax!mhres!vrh
"Experience comes with the amount of equipment ruined."

stephen@ziebmef.uucp (Stephen M. Dunn) (05/21/89)

In article <670@spudge.UUCP> johnm@spudge.UUCP (John Munsch) writes:
$DOS versions past 3.0 have the INT 21h function call 58h which sets the DOS
$memory allocation strategy.  One of the available options for this is to
$allocate from the top down.  Consult a DOS technical manual for details on
$the parameters of the function call.

   Yes, and it also allows you to tell DOS to use the "best-fit" strategy.

   But back to the original point - allocating memory from the top down.
DON'T DO THIS WITH TSRs!  If you do, you'll end up rebooting your  machine.
Why?  Let me explain (DOS gurus can skip the rest of this article)

   When you first boot your machine, it loads in the boot sector, the BIOS,
and the BDOS (well, this is close enough for now).  Then, it loads the
file COMMAND.COM in an odd way.  Part of it (the relocating EXE loader) stays
low in memory, just above the rest of the O/S.  The rest (the command
driver) goes at the top of memory.  Then you are free to load and run programs
as usual.  Each time you return from a program to DOS, the resident part
of COMMAND.COM (the part in low memory) computes a checksum on where the
part in high memory was.  If it's okay, it jumps to it.  Otherwise, it
assumes that the program you just used clobbered it and tries to load
COMMAND.COM again into the very top of memory.  (The reason it's organized
like this is that only the largest programs will wipe COMMAND.COM out
of high memory, so it won't have to be reloaded too often).

   Now, let us say that you have set the memory allocation strategy to
get DOS to put your programs high in memory, and that you have just run
a TSR.  It will, of course, have wiped out the high-memory part of
COMMAND.COM.  The low-memory part will notice this and will try to
put it back.  Now, as I understand it, what will happen is that your TSR
will be overwritten and the machine has at least a 99.9% chance of crashing.
(the other alternative is that maybe DOS will realize that the memory is
unavailable and will crash ... I've never tried it, so I don't know which
is the case.)

   So the moral is:  if you're going to tell DOS to put things in high
memory, you have two problems:

1.  DOS will have to reload the command driver after every program you
run (not too bad on a hard drive, but a real pain in the butt if you
booted from a floppy)

2.  Put any TSRs you want into memory BEFORE switching DOS to "last-fit"
allocation.

-- 
-------------------------------------------------------------------------------
! Stephen M. Dunn              stephen@ziebmef.UUCP ! DISCLAIMER:  Who'd ever !
! Take off to the Great White North eh, ya hosehead ! claim such dumb ideas?  !
-------------------------------------------------------------------------------

sbanner1@uvicctr.UVic.ca.UUCP (S. John Banner) (05/29/89)

In article <1989May20.132014.5230@ziebmef.uucp> stephen@ziebmef.UUCP (Stephen M. Dunn) writes:
>In article <670@spudge.UUCP> johnm@spudge.UUCP (John Munsch) writes:
>$DOS versions past 3.0 have the INT 21h function call 58h which sets the DOS
>$memory allocation strategy.  One of the available options for this is to
>$allocate from the top down.  Consult a DOS technical manual for details on
>$the parameters of the function call.
>
>   Yes, and it also allows you to tell DOS to use the "best-fit" strategy.
>
>   But back to the original point - allocating memory from the top down.
>DON'T DO THIS WITH TSRs!  If you do, you'll end up rebooting your  machine.
>Why?  Let me explain (DOS gurus can skip the rest of this article)

>   Now, let us say that you have set the memory allocation strategy to
>get DOS to put your programs high in memory, and that you have just run
>a TSR.  It will, of course, have wiped out the high-memory part of
>COMMAND.COM.  The low-memory part will notice this and will try to
>put it back.  Now, as I understand it, what will happen is that your TSR
>will be overwritten and the machine has at least a 99.9% chance of crashing.
>(the other alternative is that maybe DOS will realize that the memory is
>unavailable and will crash ... I've never tried it, so I don't know which
>is the case.)

   This is was a very good explanation of the point, most informative.
Unfortunately, it has one little flaw in it.  I have written a TSR
that I have never had any complaints about, that uses exactly this
sort of a strategy.  I have this program that needs to leave a chunk
of itself available after it has been used.  The program is written
in C, and the easyest way to prevent memory fragmentation is to put
things into High memory, so...  The only reason that the problems
described here should ever happen, is if you don't properly allocate
the memory (I use Dos's memory allocation calls, and have had none
of the problems you describe, not even while I was developing the
program).

   The moral to this story is (I think), follow the rules whenever
you can, even if you have to break the rules (as TSRs often have to),
follow the rules as much as possible.

                      S. John Banner

...!uw-beaver!uvicctr!sol!sbanner1
...!ubc-vision!uvicctr!sol!sbanner1
ccsjb@uvvm.bitnet  (Please avoid this address if possible)
sbanner1%sol.uvic.cdn@ubc.csnet
sbanner1@sol.UVic.ca