Using _psp to Check Pointers in an Application

ID: Q66127

6.00 6.00a 6.00ax 7.00 | 1.00 1.50

MS-DOS                 | WINDOWS
kbprg

The information in this article applies to:

SUMMARY

To implement a pointer checking routine in your application developed for the MS-DOS operating system, first determine the beginning memory address of your program. The program segment prefix (PSP) is set to the lowest segment of available memory statically allocated by the program. However, when an application uses malloc() to dynamically allocate memory, it can receive memory at an address less than _psp. A well-designed pointer checking routine must account for this behavior.

MORE INFORMATION

When MS-DOS loads an .EXE or .COM file into memory, it creates the PSP in the lowest segment of the largest contiguous block of available memory. Other blocks of memory may be available below the location of the PSP; these blocks of memory are usually fairly small. In an application that uses the /Zr compiler option to implement pointer checking, when MS-DOS returns a pointer to a memory segment that has an address lower than that of the PSP, the application discards the segment and calls MS-DOS to request another segment. The application repeats this process until MS-DOS returns a segment value greater than _psp.

To implement a similar scheme in an application, use the techniques below to call a function instead of calling malloc() directly. However, because the application start-up code calls malloc() directly to allocate space for the environment and for arguments, the environment and argument segments may be less than _psp. Further, the code example below does not implement pointer checking, it only enables an application to implement pointer checking by comparing segment values against _psp.

Another method for the application to receive pointers to segments at locations greater than _psp is to modify the start-up code to store the value of _psp at _aseglo, the location at which the application stores the lower segment limit when it implements pointer checking. The code required to check the segment returned by an MS-DOS allocation against the value at _aseglo and to reject nonconforming segments is already implemented. If the environment and argument segments must be greater than _psp, modify the start-up code in a similar manner. If you assign the value of _psp to _aseglo before the start-up code allocates space for these variables, their segment values will be greater than _psp. However, Microsoft does not guarantee the implementation of this feature in any future release of the C compiler.

If a malloc() call causes the application to allocate a new segment from the operating system, the application calls MS-DOS to request only the amount of memory required to satisfy the request. In subsequent calls, malloc() requests additional 8K blocks of memory until the segment grows to 64K and is full. Because the blocks of memory below the PSP are typically small, they may not be allocated by the first malloc() calls. You cannot predict with any certainty when these blocks of memory will be allocated.

Sample Code

void * _new_malloc(size_t size)
{
   void *temp_ptr;

   temp_ptr = malloc(size);
   while ((temp_ptr != NULL) && (FP_SEG(temp_ptr) < _psp))
      temp_ptr = malloc(size);
   return temp_ptr;
}

Additional reference words: kbinf 6.00 6.00a 6.00ax 7.00 1.00 1.50 R6013 illegal far-pointer use KBCategory: kbprg KBSubcategory: CLngIss Keywords : kb16bitonly

Last Reviewed: July 18, 1997