home *** CD-ROM | disk | FTP | other *** search
- ----------------------------------------------------------------------
-
- Text of the article:
-
- MAPPING DOS MEMORY ALLOCATION
-
-
- The concept of a memory control block (MCB) was introduced in MS-DOS,
- Version 2.0, as the operating system's basic method of tracking memory
- allocation for application programs and installable device drivers. In this
- article, I'll discuss how DOS uses memory control blocks and will present a
- Turbo C (typist used Power C) program named MCB.C that prints out DOS' current
- state of memory allocation. First, it might be useful to review how the PC
- uses memory.
-
- Address (Hex) Memory Usage
- _______________________________________________________________
- | | |
- | 0000:0000 | Interrupt vector table |
- | 0040:0000 | ROM BIOS data area |
- | 0050:0000 | DOS parameter area |
- | 0070:0000 | IBMBIO.COM / IO.SYS (See note 1 below) |
- | mmmm:mmmm | IBMDOS.COM / MSDOS.SYS (See note 1 below) |
- | mmmm:mmmm | CONFIG.SYS - specified information |
- | | (device drivers and internal buffers) |
- | mmmm:mmmm | Resident COMMAND.COM |
- | mmmm:mmmm | Master environment |
- | mmmm:mmmm | Environmrnt block # 1 |
- | mmmm:mmmm | Application program # 1 |
- | . | . |
- | . | . |
- | . | . |
- | mmmm:mmmm | Environment block # n |
- | mmmm:mmmm | Application # n |
- | xxxx:xxxx | Transient COMMAND.COM |
- | A000:0000 | Video buffers and ROM |
- | FFFF:000F | Top of 8086 / 88 address space |
- |----------------|----------------------------------------------|
- | Note 1: PC-DOS uses IBMBIO.COM and IBMDOS.COM |
- | MS-DOS uses IO.SYS and MSDOS.SYS instead. |
- |---------------------------------------------------------------|
-
- FIGURE 1: The PC memory map
-
- Figure 1 shows the major aspects of the PC memory map as documented by
- Microsoft and IBM. Addresses are shown in hexadecimal segment:offset form.
- Numeric addresses give absolute memory locations for those items that are
- always invariant in a PC running under MS-DOS, Versions 2.0 and later.
- Symbolic addresses vary according to the version of DOS you are running and
- the number and types of applications presently in memory. More than one
- program will be in memory if one or more terminate-and-stay-resident (TSR)
- program has been installed.
- The program MCB.C in Listing One, page 94, computes and prints out specific
- addresses shown as mmmm:mmmm in Figure 1, which includes most of the unknowns
- in the DOS memory map. The only address it cannot compute is the starting
- address of the transient portion of COMMAND.COM (denoted by address
- xxxx:xxxx). MCB.C also provides insight as to how the DOS memory management
- functions do their job and can show you exactly where all your memory has gone
- the next time you run out of it on a machine overloaded with TSR's. Finally,
- MCB.C should give you ideas about how to reallocate memory appropriately
- should it become necessary. For now, I'll discuss DOS memory control blocks
- and describe where they fit it into all this.
-
- MEMORY CONTROL BLOCKS
- Microsoft and IBM document the fact that they use MCB's, but neither docu-
- ments specific details of how they use them. The contents of an MCB, also
- known as an arena header, are illustrated in figure2, page 57. An MCB contains
- three fields called the chain id, process ID (PID), and block size. Together
- these fields occupy the first 5 bytes of the MCB; the remaining 11 bytes are
- unused. An MCB always begins on a paragraph boundary and occupies exactly one
- paragraph (16 bytes) of memory. The chain id byte indicates whether this is
- the last MCB (value Z) or if another follows (value M). The memory block
- controlled by a given MCB always follows immediately, starting at the next
- paragraph, and has a size equal to the number of paragraphs specified in the
- block-size field of the MCB. I'll refer to these blocks of memory as memory
- blocks (MB's) to distinguish them from the MCB's. Subsequent MCB/MC pairs
- always start just after the previous pair. MCB's can be thought of as a
- forward-linked-list data structure, with the MB's they control neatly
- sandwiched in between. In normal operation, there are no gaps in this
- structure. If DOS detects any corruption in the MCB chain, it prints out an
- error message and halts the system. (I have had occasion to break the MCB
- chain deliberately during my investegations; DOS doesn't always notice.)
-
- ______________________________________________________________________
- | |
- | MCB |
- | Start Memory Control Block Fields |
- | Address ___________________________________________________ |
- | | chain | PID | blk | unused | |
- | yyy0:000 | id | | size | | |
- | |-------------------------------------------------| |
- | |
- | Offset ------> 0 1-2 3-4 5-15 |
- | |
- | |
- | where chain id = MCB chain-identification byte. Its value is |
- | Z for the last MCB in DOS' MCB chain and |
- | M otherwise |
- | |
- | PID = Process ID, or the program segment |
- | prefix of the program that 'owns' the |
- | MCB and the memory it controls. |
- | |
- | blk size = Size of the contiguous block of memory |
- | controlled by the MCB in units of |
- | paragraphs. It does not include the MCB |
- | itself. |
- |----------------------------------------------------------------------|
-
- FIGURE 2: MCB fields
-
- The first MCB/MB pair allocated by DOS is always owned by IBMDOS.COM/
- MSDOS.SYS and is the fifth PC memory region, as shown in Figure 1. The number
- of remaining MCB's depends upon whether or not any TSR's have been installed.
- Typically, any program (transient or TSR) in memory owns at least two MCB's -
- one for its copy of the environment and the other for its code and data. If
- the program has allocated additional space (for example as internal buffer
- space), it may own more MCB's. If a TSR has freed its environment block (as
- some do), it may own only one MCB.
-
- DOS MEMORY-MANAGEMENT FUNCTIONS
- Starting with Version 2.0, all versions of DOS contain functions to
- allocate memory (function 48H), free allocated memory (FUNCTION 49h), and
- modify allocated memory (function 4aH). None of these functions deal directly
- with MCB's; instead they deal with the associated MB's. Changes caused by use
- of these functions, however, are reflected in the MCB's as can be seen upon
- inspection (using my program) after use of any of these functions. In
- addition, DOS 3.x provides function 58h (get/change memory allocation
- strategy), which controls how memory is allocated: first fit (the default in
- DOS 3.x and that used in DOS 2.x); last fit; and best fit.
- Note that DOS (actually COMMAND.COM) uses these functions to allocate
- two memory blocks automatically when it loads and runs a transient program
- (using the DOS EXEC function 4bH) and frees them upon termination. Any other
- memory allocated by an application using these functions must subsequently be
- freed or it will remain in memory. None of the memory allocated for a TSR is
- released automatically, of course.
- A more detailed discussion of these memory-management functions would
- warrant a separate article. After using my program, all of them should make
- more sense (the official documentation for them is a little cryptic). Also,
- with the understanding of DOS memory allocation provided by my program and
- this article, DOS could be bypassed altogether for memory management, although
- that is not my intention.
-
- LOCATING MCB's IN MEMORY
- Two of a program's MCB's can be found easily: one MCB is one paragraph
- above its PSP; the other is one paragraph above the environment block. The
- segment address of the copy of the environment is contained in the word at
- offset 2cH in the PSP. (This is not true for the master copy of COMMAND.COM.
- Under DOS 2.0-3.2, the environment pointer for the master copy of COMMAND.COM
- has a dummy value of 0000. DOS 3.3 corrects this oversight.) This doesn't help
- you find the MCB's lower in memory, though, because the MCB's are linked only
- in the forward direction. The trick is to locate the first MCB in memory-once
- you have done that, it is a simple matter to visit them all.
- So how do you find the first MCB? There is no documented way. Any number of
- brute-force methods have occurred to me, none of them very satisfactory.
- Fortunately, there is a better method that involves the undocumented DOS
- Invars function 52H. When this function call is complete, ES:[BX-2] points to
- a word that contains the segment address of the first MCB. Because all MCB's
- start on a paragraph boundary, that's all you need to locate the first one.
-
- OBTAINING ADDITIONAL INFORMATION
- Each MCB/MB pair is owned by a PID, which is nothing more than the segment
- address of the PSP of the program that owns the memory. From the PSP address,
- you can derive other useful information. First, you can find the location of
- the program's copy of the environment, as mentioned earlier. Another
- (undocumented) piece of information you can discover is the PID of the parent
- process, which is located at the word PSP:16H. In DOS 3.x only, you can also
- find the name of the owner program.
- The PID owner name consists of the drive, path, and filename of the pro-
- gram allociated with the PID. To find it, first locate the copy of the
- environment for any program other than the operating system files IBMDOS.COM
- and COMMAND.COM (these must be treated separately) using the word at PID:2Ch.
- Each string in the environment is in ASCIIZ form (which ends in a NULL, the
- ASCII character with value 0). Search for the first double NULL (sometimes
- there is more than one).
- If a word count of 0001 immediately follows the double NULL (indicating
- that only one more ASCIIZ string is left in the environment), then the owner
- of the program is given by the ASCIIZ string immediately following. If the end
- of the environment is reached and no such pattern is found, the owner is
- unknown. (This will always be the case for DOS 2.x) Note that if a TSR has
- freed its environment block, the owner name thus found is likely to be
- inaccurate because the TSR no longer owns it and it may have been claimed by a
- different program (typically, the next TSR or transient program will claim
- it).
-
- THE MCB PROGRAM
- The procram MCB.C in listing One is heavily commented, so I'll make only
- a few general comments here.
- I used the small-memory model of Turbo C, Version 1.5, (as mentioned before
- the typist used Power C) to compile and link MCB.C into MCB.EXE. The
- complications of doing so are manifested in the explicit declarations of some
- far and huge pointers, as explained in the comments.
- I used no Turbo C library calls specific to either Turbo C itself or to
- the IBM PC, so other C compilers should have no problem compiling the program,
- and it should run on any MS-DOS machine, even one not compatible with the IBM
- PC. (I ran it without any difficulty on a DEC Rainbow under MS-DOS 2.11.)
- (Typist note: See the file MCB_READ.ME for a problem I encountered in
- compiling with Quick C)
- The program itself is a straightforward implementation using the material
- discussed earlier in this article. The first MCB in memory is located using
- DOS function 52h. The program then visits each one and computes and prints out
- information on each MCB/MB. See the large comment block at the end of function
- prn_header() in Listing One (the MCB.C program) for a detailed description of
- the fields printed for each MCB.
- Examples 1-6, pages 57-63, contain the screen output of several
- illustrative examples. The conditions under which each was run are summarized
- in the captions. The effects of other DOS commands run are also shown when
- they are relevant to the discussion.
- Example 1 illustrates the minimum number of MCB/MB pairs because no extra
- device drivers or TSR's have been installed. The curious free embedded MCB 03
- seems to be a leftover from the DOS boot process-it seems strange that DOS
- should leave it there. Also note the use of memory by MCB.EXE and the final
- large free block. Many application programs claim all of the remaining memory
- for themselves when they run, and I was curious as to why MCB.EXE didn't.
- Because it was an .EXE file, it was possible that its .EXE header specified a
- smaller amount of memory. I checked the header and found it was set to claim
- as much free memory as was available. I finally traced the return of memory to
- DOS by examining the Turbo C start-up code that was executed prior to giving
- main() control. Sure enough, this code called DOS function 4Ah. The parent
- address (022Bh) of IBMDOS.COM in this example is also interesting.
-
- C>mcb
-
- ====================================================================
- MCB MCB ID PID MB PAR- ENV OWNER
- NO. SEG SIZE ID BLK?
- ====================================================================
- 01 0973 M 008 8208 022B N IBMDOS.COM/MSDOS.SYS
- 02 0B75 M 0B76 3376 0B76 N COMMAND.COM COPY # 1
- 03 0C49 M 0000 48 F000 N FREE MEMORY CONTROL BLOCK
- 04 0C4D M 0B76 160 0B76 N COMMAND.COM COPY # 1
- 05 0C58 M 0C5E 64 0B76 Y C:\TURBOC\DEV\MCB.EXE
- 06 0C5D M 0C5E 71232 0B76 N C:\TURBOC\DEV\MCB.EXE
- 07 1DC2 Z 0000 530384 F000 N FREE MEMORY CONTROL BLOCK
- ====================================================================
- Example 1: System booted with no CONFIG.STS and no AUTOEXEC.BAT. (I
- was in the directory C:\TURBOC\DEV, where MCB.EXE resides on my system,
- for this and all subsequent examples.)
-
- In Example 2, the size of the MB controlled by MCB 01 and owned by
- IBMDOS.COM shows an increase of 8,144 bytes. The extra space was allocated
- during the boot process in response to the statements in CONFIG.SYS. These
- statements caused extra storage to be allocated for the installation of the
- device driver ANSI.SYS as well as that needed to carry out the FILES=50 and
- BUFFERS=20 commands. This block grows much larger when VDISK.SYS is
- installed. Try it.
-
-
- C>type \config.sys
- device=c:\dos\ansi.sys
- files=50
- buffers-20
- lastdrive=z
-
- C>mcb
-
- ====================================================================
- MCB MCB ID PID MB PAR- ENV OWNER
- NO. SEG SIZE ID BLK?
- ====================================================================
- 01 0973 M 0008 16352 022B N IBMDOS.COM/MSDOS.SYS
- 02 0D72 M 0D73 3376 0D73 N COMMAND.COM COPY # 1
- 03 0E46 M 0000 48 F000 N FREE MEMORY CONTROL BLOCK
- 04 0E4A M 0D73 160 0D73 Y COMMAND.COM COPY # 1
- 05 0E55 M 0E5B 64 0D73 Y C:\TURBOC\DEV\MCB.EXE
- 06 0E5A M 0E5B 71232 0D73 N C:\TURBOC\DEV\MCB.EXE
- 07 1FBF Z 0000 522240 F000 N FREE MEMORY CONTROL BLOCK
- ====================================================================
- Example 2: The PC rebooted with the CONFIG.SYS shown and no AUTOEXEC.BAT
-
-
- In Example 3, the DOS 3.3 command FASTOPEN is seen to be a memory-resident
- program that owns two blocks of memory-one for a copy of the environment and
- one for the resident code itself, which is the typical case.
-
-
- C>type \autoexec.bat
- path c:\dos;c:\util;c:\turboc;c:\util\norton;c:\masm;c:\pe
- prompt $p$g
- mgc
- astclock
- subst u: c:\util
- fastopen c:
- cls
-
- C>mcb
-
- ====================================================================
- MCB MCB ID PID MB PAR- ENV OWNER
- NO. SEG SIZE ID BLK?
- ====================================================================
- 01 0973 M 0008 16352 022B N IBMDOS.COM/MSDOS.SYS
- 02 0D72 M 0D73 3376 0D73 N COMMAND.COM COPY # 1
- 03 0E46 M 0000 48 F000 N FREE MEMORY CONTROL BLOCK
- 04 0E4A M 0D73 160 0D73 Y COMMAND.COM COPY # 1
- 05 0E55 M 0E5F 128 0D73 Y C:\DOS\FASTOPEN.EXE
- 06 0E5E M 0E5F 2896 0D73 N C:\DOS\FASTOPEN.EXE
- 07 0F14 M 0F1E 128 0D73 Y C:\TURBOC\DEV\MCB.EXE
- 08 0F1D M 0F1E 71232 0D73 N C:\TURBOC\DEV\MCB.EXE
- 09 2082 Z 0000 519120 F000 N FREE MEMORY CONTROL BLOCK
- ====================================================================
- Example 3: The PC rebooted with the CONFIG.SYS in Example 2 and an
- AUTOEXEC.BAT file with the contents shown.
-
-
- Example 4 shows that the DOS GRAPHICS command is also a TSR and that it
- owns two more blocks of memory. Some TSR programs free their copy of the
- environment before executing the DOS TSR function. Such programs will not only
- have no environment block but also the owner of the remaining block holding
- the resident code may be incorrect because the owner string resides in the
- freed environment block. A TSR may have also allocated additional memory
- before exiting to DOS, in which case it would own additional memory blocks,
- which MCB.EXE would report.
-
- C>graphics
-
- C>mcb
-
- ====================================================================
- MCB MCB ID PID MB PAR- ENV OWNER
- NO. SEG SIZE ID BLK?
- ====================================================================
- 01 0973 M 0008 16352 022B N IBMDOS.COM/MSDOS.SYS
- 02 0D72 M 0D73 3376 0D73 N COMMAND.COM COPY # 1
- 03 0E46 M 0000 48 0F14 N FREE MEMORY CONTROL BLOCK
- 04 0E4A M 0D73 160 0D73 Y COMMAND.COM COPY # 1
- 05 0E55 M 0E5F 128 0D73 Y C:\DOS\FASTOPEN.EXE
- 06 0E5E M 0E5F 2896 0D73 N C:\DOS\FASTOPEN.EXE
- 07 0F14 M 0F1E 128 0D73 Y C:\DOS\GRAPHICS.COM
- 08 0F1D M 0F1E 2144 0D73 N C:\DOS\GRAPHICS.COM
- 09 0FA4 M 0FAE 128 0D73 Y C:\TURBOC\DEV\MCB.EXE
- 10 0FAD M 0FAE 71232 0D73 N C:\TURBOC\DEV\MCB.EXE
- 11 2112 Z 0000 516816 0F14 N FREE MEMORY CONTROL BLOCK
- ====================================================================
- Example 4: Running the DOS command GRAPHICS
-
-
- In Example 5, the secondary copy of COMMAND.COM owns three blocks of memory
- for some reason. I don't know why, but it's interesting.
-
- C>command
-
- The IBM Personal Computer DOS
- Version 3.30 (C)Copyright International Business Machines Corp 1981,1987
- (C)Copyright Microsoft Corp 1981, 1986
-
- C>mcb
-
- ====================================================================
- MCB MCB ID PID MB PAR- ENV OWNER
- NO. SEG SIZE ID BLK?
- ====================================================================
- 01 0973 M 0008 16352 022B N IBMDOS.COM/MSDOS.SYS
- 02 0D72 M 0D73 3376 0D73 N COMMAND.COM COPY # 1
- 03 0E46 M 0000 48 0F14 N FREE MEMORY CONTROL BLOCK
- 04 0E4A M 0D73 160 0D73 Y COMMAND.COM COPY # 1
- 05 0E55 M 0E5F 128 0D73 Y C:\DOS\FASTOPEN.EXE
- 06 0E5E M 0E5F 2896 0D73 N C:\DOS\FASTOPEN.EXE
- 07 0F14 M 0F1E 128 0D73 Y C:\DOS\GRAPHICS.COM
- 08 0F1D M 0F1E 2144 0D73 N C:\DOS\GRAPHICS.COM
- 09 0FA4 M 0FAD 112 0FAD N COMMAND.COM COPY # 2
- 10 0FAC M 0FAD 3376 0FAD N COMMAND.COM COPY # 2
- 11 1080 M 0FAD 160 0FAD Y COMMAND.COM COPY # 2
- 12 108B M 1095 128 0FAD Y C:\TURBOC\DEV\MCB.EXE
- 13 1094 M 1095 71232 0FAD N C:\TURBOC\DEV\MCB.EXE
- 14 21F9 Z 0000 513120 0F14 N FREE MEMORY CONTROL BLOCK
- ====================================================================
- Example 5: Installing a secondary copy of COMMAND.COM
-
-
- Example 6 shows that the space formerly occupied by the secondary
- COMMAND.COM has been freed upon execution of the EXIT command. You can install
- more than one secondary COMMAND.COM if desired, and you can remove each one in
- reverse order with an EXIT command.
-
- C>exit
-
- C>mcb
-
- ====================================================================
- MCB MCB ID PID MB PAR- ENV OWNER
- NO. SEG SIZE ID BLK?
- ====================================================================
- 01 0973 M 0008 16352 022B N IBMDOS.COM/MSDOS.SYS
- 02 0D72 M 0D73 3376 0D73 N COMMAND.COM COPY # 1
- 03 0E46 M 0000 48 0F14 N FREE MEMORY CONTROL BLOCK
- 04 0E4A M 0D73 160 0D73 Y COMMAND.COM COPY # 1
- 05 0E55 M 0E5F 128 0D73 Y C:\DOS\FASTOPEN.EXE
- 06 0E5E M 0E5F 2896 0D73 N C:\DOS\FASTOPEN.EXE
- 07 0F14 M 0F1E 128 0D73 Y C:\DOS\GRAPHICS.COM
- 08 0F1D M 0F1E 2144 0D73 N C:\DOS\GRAPHICS.COM
- 09 0FA4 M 0FAE 128 0D73 Y C:\TURBOC\DEV\MCB.EXE
- 10 0FAD M 0FAE 71232 0D73 N C:\TURBOC\DEV\MCB.EXE
- 11 2112 Z 0000 516816 0F14 N FREE MEMORY CONTROL BLOCK
- ====================================================================
- Example 6: The secondary COMMAND.COM remains in memory until a
- DOS EXIT command is issued
-
-
- In example 7, CHKDSK reports 588,064 bytes free, whereas in Example 6
- MCB shows 516,816 bytes free in the MB controlled by MCB 11. Let's reconcile
- the differences. The free memory reported by CHKDSK is equal to 516,816 (MCB
- 11) plus 16 plus 71,232 (MCB 10).
- This makes sense. When CHKDSK runs, it has memory allocated to it (in
- fact all the remaining memory). When it reports the amount of free memory, it
- subtracts the memory needed to run itself but does not discount that needed
- for its copy of the environment, apparently reasoning that any program run
- will need to have such an environment block allocated. The extra 16 bytes in
- the equation above are needed to account for the paragraph of memory needed
- for the last MCB (11 here) itself. Also note that CHKDSK does not include the
- memory in any free memory embedded in the body of the allocation chain (such
- as MCB 03), even though such memory is available for use under the right
- conditions.
-
-
- C>chkdsk
-
- 21309440 bytes total disk space
- 53248 bytes in 2 hidden files
- 59392 bytes in 28 directories
- 9635840 bytes in 580 user files
- 11560960 bytes available on disk
-
- 652288 bytes total memory
- 588064 bytes free
-
- EXAMPLE 7:Running the DOS command CHKDSK to see how much free memory it
- reports and see how it compares to that reproted by MCB.C
-
-
- You'll also notece that the PC on which I ran this program seems to have
- only 652,360 bytes of total memory, which is 3,072 bytes less than the full
- 640k (655,360 bytes) of memory that is actually installed. This is an example
- of memory being hidden from DOS. My computer was an IBM PC XT equipped with a
- Paradise graphics card (which provides for monochrome text and CGA graphics on
- an IBM monochrome monitor). This video card also needs a memory-resident
- program (called MGC.COM, see the contents of the AUTOEXEC.BAT file in Example
- 3) installed in order for it to function. So why doesn't MGC.COM show up in
- one of the MB's?
- It occupies the top 3,072 bytes of memory. After installing itself it
- modifies DOS' record of memory stored in word 40h:13h and does a warm reboot,
- which reinitializes the computer without doing a memory check. The reason for
- this procedure is that MGC.COM must be in memory even when DOS is not being
- used (for example, for some games that need to be booted from a floppy). The
- MCB/MB scheme is used only by DOS and wouldn't be sufficient in such cases.
-
- CONCLUSION
- The possible uses for this program are many. You could, for example, exam-
- ine the effect of all of the DOS memory-allocation functions detail. You could
- possibly devise a scheme to remove any TSR from memory, not necessarily in
- reverse of the order installed, without creating a hole in memory. With the
- location of the master environment known, those who need to change the
- environment frequently (for example the DOS path) and find the use of SET
- tedious, could write a full-screen version of the DOS SET command. No doubt
- you will think of other uses.
-
-
- END OF TEXT
-
-