Microsoft KB Archive/85571

From BetaArchive Wiki
Knowledge Base


(LONG) Basic PDS 7.x Memory Management

Article ID: 85571

Article Last Modified on 8/16/2005



APPLIES TO

  • Microsoft BASIC Professional Development System 7.0
  • Microsoft BASIC Professional Development System 7.1



This article was previously published under Q85571

SUMMARY

This article describes memory management using Microsoft Basic Professional Development System (PDS) version 7.0 and 7.1 for MS-DOS.

The following sections are included:

   INTRODUCTION
   COMPILED WITH NEAR STRINGS
   COMPILED WITH FAR STRINGS
   QBX.EXE ENVIRONMENT (FAR STRINGS)
   DYNAMIC versus STATIC ARRAYS
   HUGE ARRAYS
   SIZE LIMITS
   HOW TO DETERMINE AVAILABLE MEMORY
   WHAT TO DO WHEN YOUR PROGRAM RUNS OUT OF MEMORY

MORE INFORMATION
================

INTRODUCTION
------------

Basic PDS manages memory in three distinct ways:

     - Compiled with Near Strings:
       Unless otherwise specified, the default memory model for a
       compiled program is one using Near string addressing.

     - Compiled with Far Strings:
       To compile a program using Far string addressing you must use
       the /Fs switch.  This will allow variable length strings to be
       stored in multiple segments in Far memory, that is, outside of
       DGroup.

     - Interpreted (in the QBX.EXE environment) with Far Strings:
       This also uses Far string addressing.  In addition it
       implements additional data and code storage techniques unique
       to operation within the development environment.

Each of these three memory models will be discussed in detail later in
this document.  Each model represents a different way in which program
code and data is stored in Random Access Memory (RAM).  RAM itself is
also divided into three types of memory (see map at and of section):

     - Conventional MS-DOS Memory (0 up to 640K)
       This memory is subdivided into three areas:

          - Low Memory:
            This is where the Interrupt vector table and MS-DOS
            code resides.  Any TSR programs or device drivers may also
            be loaded here.  On top of that either program code
            or the QBX environment code will be loaded.

          - Near Memory (DGroup):
            This is a single Data segment used by Basic.  It can
            be up to 64K in size.

          - Far Memory:
            This is the area of memory from where DGroup stops to
            the end of the conventional MS-DOS Memory.

     - 384K Reserved I/O Address Space (Upper Memory Blocks):
       This is the area of memory between the top of Conventional
       Memory (640K) and the start of Extended Memory (1024K).  This
       area of memory can contain the following:

          - BIOS (basic input/output system), ROM chips, and
            display adapter memory.

          - Accessory cards such as network cards.

          - 64K Page frame for Expanded Memory


     - Extended Memory (XMS) driven by EMM386.EXE and HIMEM.SYS:
       This is linear memory above 1MB (1024K).

       Basic only uses the first segment (64K) of extended memory just
       above the 1MB boundary. This memory area is referred to as the
       High Memory Area. The QBX environment will load up to 60K of
       its code into this segment, that is assuming that no other
       program or portion of a program is loaded here (such as MS-DOS
       5.0).

     - Expanded Memory (EMS) driven by EMM386.EXE:
       This memory is available through an installable memory board
       in your system.  It can also be acquired using the EMM386
       memory driver to access Extended Memory as Expanded Memory.
       This memory is available to the program as four 16K pages. This
       memory can be used by the QBX environment for code and data
       storage, and is used by compiled applications only for code
       storage (except ISAM) when using overlays provided through the
       Linker utility.

                    GENERAL MEMORY MAP
                    ------------------

          =======================================
                                                <---
                                                    |
                   Expanded Memory (EMS)        <---|
                     up to 8MB on a PC              |
                    (not linear memory)         <---|
                                                    |
                                                <---|
                                                    |
          =======================================   |
                                                    |
                                                    |
                                                    |
     16MB =======================================   |
     |                                              |
     |                                              |
Extended Memory (XMS)                               |
 up to 15 MB on a PC                                |
     |                                              |
     |                                              |
     |    ---------------------------------------   |
     |           * High Memory Area 64K *           |
      1MB ---------------------------------------   |
     |                                              |
     |         -----------------------------    <---|
     |         ------ EMS Page Frame -------        |
384K Reserved  -----------------------------        |
  I/O space    ------(four 16K pages)-------        |
     |         -----------------------------    <---
     |
     |
     640K ---------------------------------------
                          .
                          .
                  Conventional Memory
                          .
                          .
        0 =======================================


COMPILED WITH NEAR STRINGS
--------------------------

Using "Near Strings" means that variable length strings are referenced
using near addressing and thus are stored in Near Memory (DGroup).

Near Memory (DGroup) can be up to 64K in size, but after
subtracting the space required for Basic's internal variables and
stack, only about 46K is left as available for your program.

The following is a breakdown of Near Memory (DGroup) and what may be
stored here when you use this memory model.  The areas of Near Memory
include: Static Data, the Stack, the Local Heap, and String Space.

Static Data:
     Data that is of a fixed size and the memory for which is fixed
     (pre allocated) prior to program execution.

     - Internal Variables:
          Variables used by Basic.  They maintain information on the
          current video mode; cursor size and visibility status; the
          next cursor row and column; MS-DOS version; and more.

     - String Literals:
          Such as "Hello" in the code:  Print "Hello".

     - DATA Statements:
          All information in a DATA Statement, both string and
          numeric.

     - Common Data:
          All Common data, named and blank common, fixed length and
          variable length data.

     - Static Arrays:
          Arrays with dimensions fixed prior to program execution.
          These arrays can not be REDIMed.

     - String Constants:
          Declared with the CONST statement, such as NAME in the code:
               CONST NAME = "BOB"
          NOTE: all numeric Constants are stored as code in the code
          segment.

     - Scalar Variables (Simple Variables):
          Non-DIMensioned variables such as X%, Y$, Count#, etc.

     - User Defined Type Variables:
          Variables DIMensioned by a TYPE...END TYPE structure.

     - Fixed Length Strings:
          String variables DIMensioned to a specific size,
          i.e. DIM Name as String * 10.
Stack:
     Temporary storage area for certain types of data, such as local
     variables in Sub Procedures.  The size by default is 3K.  This
     can be increased or decreased using the CLEAR statement.  For
     example: CLEAR,,1024  will set the stack size to 1K (1024 bytes).


Local Heap:
     Part of the Near Heap which is a portion of Near Memory (DGroup).

     The Local Heap contains:

     - Array Descriptors:
          All arrays require a descriptor.  Single dimension arrays
          require an 18-byte descriptor, and multiple dimension
          arrays require an additional 4-bytes for each additional
          dimension beyond the first.  Note that an array of variable
          length strings is really and array of 4-byte string
          descriptors (see below).

     - String Descriptors:
          Only variable length strings require a descriptor, fixed
          length strings do not.  This 4-byte descriptor describes the
          string's length and starting location in memory.  Note that
          each variable length string in an array requires a
          descriptor.

     - File Data Block Segments:
          This is where the file buffer is created to store data.  You
          specify the size of this buffer with the LEN clause at the
          end of an OPEN statement:
               OPEN "Test.txt" for Random as #1 Len = 512.

String Space:
     Places where variable length string data is stored.  In this
     memory model it is located in Near Memory (DGroup).  In other
     models (Far String model) it will be located in Far Memory.

     - Variable Length Strings:
          Only the string data is stored here, not the string
          descriptors, they are stored in the Local Heap.  This will
          be an important distinction when using the Far String memory
          model.

     - Dynamic Variable Length Strings Arrays:
          As with variable length strings, only the string data   is
          stored here.  The string descriptors and array descriptors
          are stored in the Local Heap.  Note this applies to only the
          Dynamic variable length string arrays.  The memory for these
          arrays is not allocated until runtime.  The arrays can be
          REDIMed.


The following is a breakdown of Far Memory and what may be stored
here when you use this memory model.  The areas of Far Memory include:
The Far Heap, Runtime Module Code, and the Communications Buffer.

Far Heap:
     This is the rest of conventional MS-DOS memory up to the 640K
     boundary after the demands of Low Memory, Near Memory (DGroup)
     and other components of Far Memory are met.

     - Dynamic Fixed Element Arrays:
          Again, only the array data is stored here.  The array
          descriptor is stored in the Local Heap.  Dynamic fixed
          element arrays are composed of elements with a fixed size,
          such as numbers, user defined types, or fixed length
          strings.  Being Dynamic, these arrays can be REDIMensioned
          to different lengths but the size of their elements must
          remain fixed.  This is where Huge Arrays are stored (see
          section on Huge Arrays).

Runtime Module Code:
     Programs compiled without the /O switch require a runtime module
     (BRUNXX.EXE or BRTXX.EXE).  When the program is executed the
     runtime module is loaded into memory.  If the program is compiled
     with the /O switch, as a stand alone application, the runtime
     module is not required.

Communications Buffer:
     This is an intermediate storage area for data sent or received
     from a communications port.  The default size is 512K.  It can be
     adjusted from 0 to 32,767 (32K).  This is done with the /C:XXXX
     switch on the compiler, the XXXX being the number of bytes to
     reserve for the buffer.

               COMPILED NEAR STRING MEMORY MODEL
               ---------------------------------

 MS-DOS ---> -------------------------------------- <---
 640K                Communications Buffer              |
Boundary     --------------------------------------     |
                      Runtime Module Code               |
             --------------------------------------     |
                                                        |
                                                    Far Memory
             Far Heap:                                  |
               Dynamic Fixed-Element Arrays             |
                                                        |
                                                        |
                                                        |
        ---> ====================================== <---
       |                                                |
       |     String Space:                              |
       |       Variable Length Strings                  |
       |       Dynamic Variable Length String Arrays    |
       |                                                |
       |     -------------------------------------- Near Heap
       |                                                |
       |     Local Heap:                                |
       |       Array & String Descriptors               |
       |       File Data Block Segments                 |
       |                                                |
       |     -------------------------------------- <---
    Data Group               Stack
     (DGroup)--------------------------------------
   Near Memory
       |     Static Data:
       |       Internal Variables
       |       String Literals
       |       Data Statements
       |       Common Data
       |       Static Arrays
       |       Constants
       |       Scalar Variables
       |       User Defined Type Variables
       |       Fixed Length Strings
       |
        ---> ====================================== <---
                                                        |
                          Program Code                  |
                                                    Low Memory
             --------------------------------------     |
                              MS-DOS                    |
             -------------------------------------- <---


COMPILED WITH FAR STRINGS
-------------------------

Using "Far Strings" means that variable length strings are referenced
using far addressing and thus can be stored in Far Memory.

The following is a break down of Near Memory and what may be stored
here when you use this memory model.  It is pretty much the same as
the Near Memory model when using Near Strings except for the
following:

Static Data:
     Only fixed length Common Data.  (Common data for variable
     length strings is stored in Far Memory).


The following is a break down of Far Memory and what may be stored
here when you use this memory model.  String Space is now located in
Far memory for variable length strings.  It is referred to as the
String Segments.  Note, fixed length strings and Static arrays are
still stored with all other Static Data in DGroup as before:

String Segments:

     - Local Dynamic String Array Segments:
          Data of Dynamic string arrays created within a Sub Procedure
          or Function is stored in a segment of this type.  A new
          segment is allocated for each Sub or Function.  The segment
          can be up to 64K in size.

     - Module Level String and Named Common String Segment
          This is an independent segment up to 64K in size.  This
          segment stores all data from variable length strings and
          string arrays created in the main module.  It also contains
          data from variable length strings and string arrays in Named
          Common blocks.

     - Blank Common String Segment:
          This is another independent segment up to 64K in size.  This
          segment contains data from variable strings in Blank Common
          blocks.

     - Local and Temporary String Segment:
          This is another independent segment up to 64K in size.  This
          segment is shared by all procedures and module level code.
          In it is stored all data for local and temporary variable
          length strings created in a given program.

Far Heap:
     The File Data Block is now located here.

                COMPILED FAR STRING MEMORY MODEL
                --------------------------------

  MS-DOS --> -------------------------------------- <---
   640K              Communications Buffer              |
 Boundary    --------------------------------------     |
                      Runtime Module Code               |
             --------------------------------------     |
                                                        |
             Far Heap:                                  |
               Dynamic Fixed-Element Arrays             |
               File Data Block Segments                 |
                                                    Far Memory
             --------------------------------------     |
                                                        |
             String Segments (Variable Length Strings): |
               Local & Temp. String Segment             |
               Module Level String &                    |
                   Named Common String Segment          |
               Blank Common String Segment              |
               Local Dynamic String Array Segments      |
                                                        |
         --> ====================================== <---
        |                                               |
        |    Local Heap:                            Near Heap
        |          Arrays & String Descriptors          |
        |                                               |
        |    -------------------------------------- <---
        |                    Stack
        |    --------------------------------------
   Data Group
    (DGroup) Static Data:
 (Near Memory) Internal Variables
        |        String Literals
        |        Data Statements
        |        Fixed Length Common Data
        |        Static Arrays
        |        Constants
        |        Scalar Variables
        |        User Defined Type Variables
        |        Fixed Length Strings
        |
         --> ====================================== <---
                                                        |
                          Program Code                  |
                                                    Low Memory
             --------------------------------------     |
                           MS-DOS                       |
             -------------------------------------- <---

QBX.EXE ENVIRONMENT (FAR STRINGS)
---------------------------------

The use of Far String addressing is the default in the QBX.EXE
environment.  Although memory usage and data storage does differ
considerably from compiled versions of the same program.

The following is some information that applies uniquely to the QBX
(QuickBasic Extended) environment:


Conventional Memory:
     QBX requires 315K + additional memory needed for Quick libraries
     if loaded.

Extended Memory:
     If you have a 64K block of High memory (Extended Memory) and
     nothing else is loaded there (such as MS-DOS 5.0) then QBX will
     automatically load 60K of its code here (assuming HIMEM.SYS is
     loaded).  This reduces the amount of conventional memory
     required by the QBX environment to 255K.

Expanded Memory:
     If expanded memory is available it will be used by the QBX.EXE
     environment to store some of your program's code. Only Sub
     and function procedures greater than 1K and less than 16K will
     be stored here. Subprograms larger than 16K are stored in the
     far heap in conventional memory in both Basic 7.0 and 7.1.

     QBX.EXE from version 7.1 uses expanded memory more efficiently
     than QBX.EXE from version 7.0. In 7.0, each subprogram from 1K to
     16K in size uses a full 16K of expanded memory. In 7.1,
     subprograms smaller than 16K will use expanded memory in 1K
     chunks. In 7.1, if a subprogram is 2K in size, it will use only
     2K of expanded memory. In Basic 7.0, a 1K Sub as well as a 15K
     Sub will each require a 16K chunk of expanded memory.

     To save memory in Basic 7.0, you should try to keep the size of
     your procedures smaller than 16K but as close to 16K as possible.
     In Basic 7.1, you should simply try to keep sizes less than 16K.

     You can determine the size of your procedures from within the
     environment by pressing <F2>. The number you see to the right
     of each module name is the module's size.

     NOTE: When you have one or more Sub or Function procedures, QBX
     will require a one time overhead of two 16K blocks (32K) for its
     own internal tables.


QBX.EXE Switches for Managing Memory:

/Ea:
     This will tell QBX to store fixed length arrays in expanded
     memory.  These arrays must be between 512 and 16K in size.  DO
     NOT use this switch in combination with /Es.

/Es:
     Use this switch when you have some mixed language routines in a
     quick library that access expanded memory.  If you do not use
     this switch the memory may not be available to those routines
     when they are called.  DO NOT use this switch in combination with
     /Ea.

/E:n
     This will specify the amount of expanded memory to reserve for
     use by QBX.  If this switch is not used the default is all
     available expanded memory.  If /E:0 is used then no expanded
     memory will be used and the /Ea and /Es switches are overridden.

/NOFrills
     This switch reduces the functionality of the environment and
     frees up to 19K more memory that the QBX environment would
     otherwise use.
          - No Utility menu and associated commands.
          - No Options menu and associated commands.
          - No Help menu and associated commands.


Other QBX.EXE notes:

     - The code of QBX.EXE itself is located in Low memory.

     - If a Quick library is loaded, its code is loaded in Far memory.
       The Quick library's Scalar variables, Static arrays, and Common
       variables are stored in DGroup.

     - Program code is now located in the Far Heap.

     - Static arrays (except those in Common Blocks) are now stored in
       the Far Heap.

     - Every Common Block has a variable table created for it of a
       corresponding size.  This variable table is created for every
       module that this Common Block is listed in.


                  QBX ENVIRONMENT FAR STRINGS
                  ---------------------------


  MS-DOS --> -------------------------------------- <---
   640K              Communications Buffer              |
 Boundary    --------------------------------------     |
                      Quick Library Code                |
             --------------------------------------     |
                                                        |
             Far Heap:                                  |
               Dynamic Fixed Element Arrays             |
               File Data Block Segments                 |
               User Program Code                    Far Memory
               Static Arrays (not in Blank Common)      |
                                                        |
             --------------------------------------     |
                                                        |
             String Segments (Variable Length Strings): |
               Local & Temp. String Segment             |
               Module Level String &                    |
               Named Common String Segment              |
               Blank Common String Segment              |
               Local & Dynamic String Array Segments    |
                                                        |
         --> ====================================== <---
        |                                               |
        |    Local Heap:                                |
        |      Array & String Descriptors               |
        |      String Literals                          |
        |      Data Statements                          |
        |      Fixed Length Common Data             Near Heap
        |      Static Arrays                            |
        |      Constants                                |
        |      Scalar Variables                         |
        |      User Defined Type Variables              |
        |      Fixed Length Strings                     |
        |                                               |
        |    -------------------------------------- <---
   Data Group                Stack
    (DGroup) --------------------------------------
  (Near Memory)
        |    Static Data:
        |      Quick Lib Scalar Variables
        |      Quick Lib Static Arrays
        |      Quick Lib Common Variables
        |      Internal Variables
        |      Blank Common Static Arrays
        |
         --> ====================================== <---
                           QBX Code                     |
             -------------------------------------- Low Memory
                            MS-DOS                      |
             -------------------------------------- <---

DYNAMIC versus STATIC ARRAYS
----------------------------

A Dynamic Array is one whose size is defined at run time.  This type
of array can be REDIMensioned during the execution of the program.

A Static Array is one whose size is defined at compile time and cannot
be changed at run time.

To make an array, Dynamic do any of the following:

     - Use the REDIM statement when first creating the array:

          REDIM A(20) AS STRING * 80

     - Use a simple variable for at least one of the dimensions when
       DIMensioning the array:

          d = 20
          DIM A(d,64) AS INTEGER

     - Use the array in a COMMON statement and then DIMension it
       (Dynamic arrays should *always* be placed after the COMMON
       statement):

          COMMON A()
          DIM A(64)

     - Use the REM $DYNAMIC metacommand before DIMensioning the array:

          '$DYNAMIC
          DIM A(64)

To make an array Static do any of the following:

     - DIMension the array with a literal:

          DIM A(64) AS INTEGER

     - DIMension the array with a CONSTant:

          CONST Num = 16
          DIM A(Num) AS INTEGER

     - Implicitly DIMension the array (just start assigning values to
       elements of an array).  Note, when implicitly DIMensioning an
       array you are limited to a default of 10 subscripts:

          A%(0) = 5
          A%(1) = 6
          A%(2) = 7

     - Use the REM $STATIC mettacommand:

          '$STATIC
          DIM A(64)

HUGE ARRAYS
-----------

Huge arrays are arrays that are greater than 64K in size.  These huge
arrays must be dynamically DIMensioned and must contain elements of a
fixed size.  In order to use huge arrays you must use the /AH option
for the QBX environment and/or for the Compiler.

To DIMension an array Dynamically you can either REDIM the array when
first created, use the REM $DYNAMIC mettacommand, DIMension the array
with a variable, or DIMension the array after a COMMON Statement in
which you reference that same array. (See previous section on Dynamic
versus Static arrays).

An array of "Fixed-elements" refers to an array whose elements are any
numerical type (Integer, Long, Single, Double, Currency), an array
whose elements are fixed length strings (A as String * 16) or an array
whose elements are a user defined type (NOTE: a user defined type can
not contain variable length strings).

If the array is greater than 128K, the size of each element of the
array must be a power of two (such as 2, 4, 8, 16, 32, 64, 128, 256,
and so forth). Since all numerical types have a size that is a power
of two, all you need to consider are elements that are either fixed
length strings or user defined types.

With a user defined type, it is not important for each field in the
type to be a power of two in size, but rather for the total size of
the type be a power of two.  For example:

     Type testtype
          x as integer
          y as long
     End Type

This user defined type has a size of 6 bytes, which is not a power of
two.  You must "pad" the type with additional bytes:

     Type testtype
          x as integer
          y as long
          dmmy as string * 2
     End Type

Total size is now 8, which is a power of two (2^3).
The field used for padding can be any type, but a fixed length string
is especially convenient for padding.

The above padding is necessary in huge arrays because an array element
may not span a segment boundary.  That is, each
element of an array must fit in memory in such a way that they
completely fit within a segment's boundary (aligned with the segment
boundary) with no leftover space or gap.

For example, if we have an element 32K in size, two elements will fit
evenly in a single segment (with no gaps). But if we have an element
31K in size, two elements will fit in one segment but others will have
to start in another segment, leaving a 2K gap in memory.

| 2k |  element1   |   element2  ||   element3   |   element4   | 2k |

The segment boundary is between element2 and element3.  In order for
the elements to be aligned with the segment boundary, Basic
automatically shifts the first two elements in memory. Note the 2K
gaps and the fact that no more records can be boundary-aligned after
element4.

Because of this requirement of boundary alignment, if the elements of
a huge array are not a power of two in size, the largest size this
huge array could be is under 128K. Otherwise, if the elements are a
power of two and thus able to be segment boundary aligned, the size
of the huge array is limited only by available conventional far memory
(MS-DOS 640K).

SIZE LIMITS
-----------

Data Types                Maximum                   Minimum
---------------------------------------------------------------------
Variable names            40 characters             1 character

String length ($)         32,767 characters         0 character
     [1 byte per char]

Integers (%)              32,767                    -32,767
     [2 bytes]

Long Integers (&)         2,147483,647              -2,147,483,648
     [4 bytes]

Currency (@)       922,337,203,685,477.5807  -922,337,203,685,477.5808
     [8 bytes]

Single-precision (!)
     [4 bytes]
     Pos                  3.402823E+38               1.401298E-45
     Zero                 0
     Neg                 -1.401298E-45              -3.402823E+38
     Pos with /Fpa        3.402823E+38               1.175494E-38
     Zero with /Fpa       0
     Neg with /Fpa       -1.175494E-38              -3402823E+38

Double-precision (#)
     [8 bytes]
     Pos              1.797693134862315D+308    4.940656458412465D-324
     Zero             0
     Neg             -4.940656458412465D-324   -1.797693134862315D+308
     Pos with /Fpa    1.79769313486232D+308     2.2250738585072D-308
     Zero with /Fpa   0
     Neg with /Fpa   -2.2250738585072D-308     -1.79769313486232D+308



Arrays                          Maximum                 Minimum
----------------------------------------------------------------------
Array size (all elements)
     Static                     65,535 bytes (64K)      1
     Dynamic           Available Memory (MS-DOS 640K)   0

Array Dimensions                8                       1

Array subscripts                32,767                  -32,768



Files & Procedures                 Maximum                   Minimum
---------------------------------------------------------------------
Number of arguments                60 interpreted            0

Nesting of include files           5 levels                  0

Procedure size (interpreted)       65,535 bytes (64K)        0

Module size (compiled)             65,535 bytes (64K)        0

Overlay size                       128K                      0

Data Files open simultaneously     255                       0

Data file record number            2,147,483,647             1

Data file record size(bytes)       32,767 (32K)              1

Data file size                     Available disk space      0

Path names                         127 characters            1

HOW TO DETERMINE AVAILABLE MEMORY
---------------------------------

There are two Basic Functions you can use to find out how much of
certain kinds of memory is available.  These are the FRE Function and
the STACK Function.

The value returned by FRE is determined by the argument passed to it,
as well as weather or not you are using Far String addressing.  Here
are some examples:

Function        Output with Near Strings       Output with Far Strings
----------------------------------------------------------------------
FRE(A$)         Unused space in DGroup         Unused space in segment
                                               where A$ is stored.

FRE("")         Unused space in DGroup         Unused space for
                                               temporary strings.

FRE(-1)         Total unused memory            Total unused memory

FRE(-2)         Unused Stack space             Unused Stack space

FRE(-3)         Available EMS                  Available EMS
                (expanded memory)              (expanded memory)


NOTE: FRE(-2) returns the amount of Stack space never used by the
program, sort of like a high water mark for the Stack.  The value
returned will get smaller as you program uses more of the Stack.  If
the amount of Stack space being used decreases, the value returned by
this function will not change.  The value of FRE(-2) may not be
accurate when used in the immediate window of the QBX environment.

The STACK function returns the maximum Stack size that can be
allocated.  This is a combination of the unused Stack space of the
current Stack setting as well as the rest of the unused space in
DGroup.

To obtain the amount of free DGroup memory when using Far String
addressing use the following equation:

     FreeDG& = STACK - FRE(-2)

WHAT TO DO WHEN YOUR PROGRAM RUNS OUT OF MEMORY
-----------------------------------------------

In General:
     - Reduce size of your MS-DOS buffers (in CONFIG.SYS)
     - Eliminate any terminate-and-stay-resident (TSR) programs
     - Eliminate non-essential device drivers under MS-DOS.
     - If in the QBX environment, unload any files that are not needed
       for your program.
     - Make your program smaller.
     - If you have Huge arrays (>64K) make sure to use the /Ah option
       (see previous section on Huge arrays).
     - Make sure your arrays have elements of a fixed size.
     - When compiling with BC.EXE, do not use /D if possible.
     - When linking use stub-files whenever possible.
       (pg. 538-539 "Basic 7.0: Programmer's Guide" for 7.0/7.1) .
     - Use a smaller File buffer in the OPEN statement's LEN clause.
     - Use Link Overlays. (pg. 612-614 "Basic 7.0: Programmer's
       Guide").

DGroup Memory:
     You may be out of space in DGroup even if you still have space
     left in Far memory and/or extended memory.

     Use the following statement to find out how much DGroup you
     have left:  PRINT STACK - FRE(-2)

     - Reduce stack size to the minimum that your program requires
       (Using the CLEAR Statement, see manual).
     - Use Fixed Length strings whenever possible
     - Use fewer string literals and DATA statements, read data in
       from a file.
     - Use DEFINT A-Z at the top of your modules. This makes the
       default data type integer.
     - Declare your arrays as DYNAMIC
       (see previous section on Dynamic versus Static).
     - Use Far sting option (/Fs)
     - If in the environment, put your Functions and Procedures into a
       Quick library.
     - NOTE: within the QBX environment
       every Common block has a variable table created for it of a
       corresponding size.  This variable table is created for every
       module that this Common block is listed in. So do not list a
       Common block in a module unless you need it to be there.


Extended Memory:
     Only the QBX environment will take advantage of Extended memory.

     - Make sure it is available.  Load QBX without the extended
       memory driver. Execute  PRINT FRE(-1) in the Immediate window,
       note the value returned, exit QBX.  Install the extended memory
       driver.  Load QBX and execute PRINT FRE(-1) as before.  If
       extended memory is available the second value should be about
       60K greater than the first.


Expanded memory:
     Only the QBX environment and a compiled program using Overlays
     will take advantage of Expanded memory.

     - Make sure expanded memory is available. Load QBX and execute
       PRINT FRE(-3) in the immediate window, which should return the
       amount of available Expanded memory. If it returns an error
       "Feature unavailable", then you either do not have expanded
       memory or the driver is not loaded or loaded incorrectly.
       Check the "Getting Started" manual under "Memory Management of
       QBX" for more information.
                


Additional query words: BasicCom 7.00 7.10 EMM386.EXE EMM386.SYS

Keywords: KB85571