[comp.sys.ibm.pc] help needed with memory organizatio

awylie@pyr1.cs.ucl.ac.uk (06/10/88)

Hello,
     can anyone tell me the format of a DOS memory control block? My copy
of the MS programmers Reference does not give this information?
     Also, how can I locate the first such block in memory and how can I
determine how much RAM a PC has installed?
    thanks!

------------------------------------------------------------
Andrew Wylie, University of London Computer Centre,
20 Guilford Street, London WC1N 1DZ, England.

JANET:      andrew@uk.ac.ulcc.ncdlab          "I can't complain,
UUCP:       ..!mcvax!ukc!cs.ucl.ac.uk!awylie   but sometimes I still do."
ARPA:       awylie@cs.ucl.ac.uk
BITNET:     andrew%uk.ac.ulcc.ncdlab@ac.uk

If replying please give a UUCP path from mcvax to
your site.

aronoff@garfield (Avram Aronoff) (06/17/88)

In article <39500012@pyr1.cs.ucl.ac.uk> awylie@pyr1.cs.ucl.ac.uk writes:
>     Can anyone tell me the format of a DOS memory control block?
>     Also, how can I locate the first such block in memory?

The following information comes from the Waite Group's book _MS-DOS Papers_.
A memory block begins with a paragraph which begins with the following
*packed* structure (no pad bytes!)
	union block_header {
		struct {
			char	signature;
			short	owner;
			short	size;
		} info;
		char	paragraph[16];
	};
Signature is 'M' for all blocks except the last, for which it is 'Z'.
Owner is (usually) the segment of the PSP of the process which allocated the
block. PSPs are those blocks which own themselves.
Size is in paragraphs.

The first block is found using the undocumented 'list-of-lists' system call.
Do 'mov ah,52h; int 21h'. This gives a pointer to the list of lists in es:bx.
Then es:[bx-2] contains the segment of the first memory block.

							Hymie

dixon@zephyrus.steinmetz (Walter V. Dixon) (06/21/88)

Under DOS 3.0 and above,  one can obtain the listhead of the
memory control block chain using the undocumented int 21h ah=52h.
This function returns a pointer to a "list of lists".  The initial
paragraph of the first MCB is at es:[bx-2].  Each MCB has the
following structure:

typedef struct sMCB {
  BYTE		MCB_B_Signature;	/* Block signature */
  WORD		MCB_W_Owner;		/* PSP of owner */
  WORD		MCB_W_Size;		/* Size of MCB (paragraphs) */
  BYTE		MCB_T_Unused[11];	/* Not used by DOS */
  BYTE		MCB_T_Data[1];		/* Data begins here */
} MCB;

#define MCB_C_NotLastBlock	'M'
#define MCB_C_LastBlock		'Z'

All MCBs except the last have a signature of M;  the last has a
signature of Z.  One traverses this list by adding MCB_W_Size+1 to
the segment of the current MCB.  MCB_W_Owner=0 indicates that the
block is free;  all other values indicate that the block is owned.
In most cases MCB_W_Owner has a PSP.  When IBMBIO loads drivers
it allocates memory from this list;  of course, drivers do not have
a PSP --  some other value is used.

NB: The free memory computed by adding the sizes of any unowned
MCBs will differ from that reported by chkdsk.  Chkdsk computes
the free memory by subtracting the memory size in the PSP from the
PSP segment (neglecting any other unallocated blocks).

You will have to get the total memory from the PSP (if a COM file)
or from BIOS.

I hope this helps.

Walt Dixon		(ARPA:     Dixon@GE-CRD.ARPA        )
			(US Mail:  General Electric Corp R&D)
			(          PO Box 8                 )
			(          Schenectady NY 12345     )
			(Phone:    518-387-5798             )