How to Change the MS-DOS Memory Allocation Strategy

ID: Q58919

5.10 6.00 6.00a 6.00ax 7.00 | 1.00 1.50

MS-DOS                      | WINDOWS
kbprg

The information in this article applies to:

SUMMARY

When MS-DOS allocates memory for your program, it uses a firstfit allocation strategy by default. You can change MS-DOS's default strategy to a bestfit, lastfit, or back to firstfit strategy with a call to Interrupt 21h Function 58h.

MORE INFORMATION

A firstfit strategy forces MS-DOS to search from low addresses in memory to high addresses, and allocate the first available block of memory large enough for the requested allocation.

A bestfit strategy forces MS-DOS to search all addresses in memory and allocate the smallest block still large enough to fill the requested allocation.

A lastfit strategy forces MS-DOS to search from high addresses in memory to low addresses, and allocate the first available block of memory large enough for the requested allocation.

The bestfit algorithm is the slowest to execute since all free memory is searched, but results in the least memory fragmentation during multiple allocations and frees. Conversely, the firstfit and lastfit strategies are fastest to execute, but result in a higher degree of memory fragmentation.

Note that changing the allocation strategy only noticeably changes the way that a call to _dos_allocmem(), halloc(), or Interrupt 21h Function 48h allocates memory from MS-DOS. The malloc() and calloc() families of routines allocate memory from the memory pool assigned to your program by MS-DOS. They are affected by MS-DOS's internal allocation strategy only when the free memory pool for your program is empty and MS-DOS is required to add new memory to your program's pool.

Sample Code

/* The following two functions use in-line assembly to set and
   get the MS-DOS allocation strategy:
*/ 

#define ALLOCATION_STRATEGY 0x58
#define GET_STRATEGY        0x00
#define SET_STRATEGY        0x01

/********************************************************/ 
/* Set_fittype - Set MS-DOS allocation strategy         */ 
/* Parameters : strategy_type, defined as:              */ 
/*          FIRSTFIT = 0x00                             */ 
/*          DEFAULT  = 0x00                             */ 
/*          BESTFIT  = 0x01                             */ 
/*          LASTFIT  = 0x02                             */ 
/* Return Value :                                       */ 
/*          -2 = Invalid Allocation strategy            */ 
/*          -1 = Invalid Function to Int 21h Func 58h   */ 
/*               Should never happen.                   */ 
/*           Otherwise, returns newly set strategy      */ 
/********************************************************/ 

int set_fittype ( unsigned strategy_type )
{
    int return_value;

    if (( strategy_type < 0 ) || ( strategy_type > 2))
    {
        return ( -2 ) ;
    }
    else
    {
        _asm {
                mov     ah, ALLOCATION_STRATEGY
                mov     al, SET_STRATEGY
                mov     bx, strategy_type
                int     21h

                jnc     no_error            ; Branch if no error
                mov     ax, -1              ; Return -1 on error

           no_error:
                mov     return_value, ax    ; -1 if error, otherwise
                                            ; returns current strategy
            }
    }
    return ( return_value ) ;
}

/********************************************************/ 
/* Get_fittype - Returns current allocation strategy.   */ 
/* Parameters : None                                    */ 
/* Return Value :                                       */ 
/*           0 = Firstfit strategy                      */ 
/*           1 = Bestfit strategy                       */ 
/*           2 = Lastfit strategy                       */ 
/********************************************************/ 

int get_fittype ( void )
{
    unsigned return_value;

    _asm {
             mov     ah, ALLOCATION_STRATEGY
             mov     al, GET_STRATEGY
             int     21h
             jnc     no_error            ; Branch if no error
             mov     ax, -1              ; Return -1 on error

         no_error:
             mov     return_value, ax    ; -1 on error, otherwise
                                         ; current strategy
                 }

        return ( return_value ) ;
}

If your compiler supports in-line assembly, you should use the above functions because of their speed since they do not require the C overhead.

If you are using a version of the compiler that does not support in- line assembly, such as C 5.0, C 5.1, QuickC 1.0, and QuickC 1.01, the above functions can be translated as follows:

#include <dos.h>  /* as well as the other #defines listed above */ 

int set_fittype ( unsigned strategy_type )
{
    union REGS inregs, outregs;
        int return_value;

        if (( strategy_type < 0 ) || ( strategy_type > 2))
        {
                return ( -2 ) ;
        }
        else
        {
        inregs.h.ah = ALLOCATION_STRATEGY ;
        inregs.h.al = SET_STRATEGY ;
        inregs.x.bx = strategy_type ;
        int86 ( 0x21, &inregs, &outregs ) ;

        if ( outregs.x.cflag )
            return ( -1 ) ;
        else
            return ( outregs.x.ax ) ;
        }
}

int get_fittype ( void )
{
    union REGS inregs, outregs;
    unsigned return_value;

    inregs.h.ah = ALLOCATION_STRATEGY;
    inregs.h.al = GET_STRATEGY;

    int86 ( 0x21, &inregs, &outregs ) ;

    if ( outregs.x.cflag )
        return ( -1 ) ;
    else
        return ( outregs.x.ax ) ;
}

Additional reference words: kbinf 1.00 1.50 5.10 6.00 6.00a 6.00ax 7.00 KBCategory: kbprg KBSubcategory: CRTIss Keywords : kb16bitonly

Last Reviewed: July 18, 1997