home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 102 / MSDOWNLD.ZIP / BQ0083.EXE / QB4MEMAN.TXT
Text File  |  1989-06-21  |  29KB  |  754 lines

  1. Memory Management in QuickBASIC 4.x, BC 6.00 (Complete Guide) [B_QuickBas]
  2.  
  3. 4.00 4.00b 4.50
  4. MS-DOS
  5. MSINTERNAL | B_BasicCom appnote SR# S890614-47 QB4MEMAN.ARC Snnnnn.EXE
  6.  
  7. Summary:
  8.  
  9. Programmers may wish to understand how Microsoft QuickBASIC and
  10. Microsoft BASIC Compiler arrange memory in order to write programs
  11. that make efficient use of system resources. The QuickBASIC language
  12. provides a variety of data types and modular code constructs that
  13. allow you to manage the data and code of your programs.
  14.  
  15. This application note applies to Microsoft QuickBASIC Versions 4.00,
  16. 4.00b, and 4.50 for MS-DOS and to Microsoft BASIC Compiler Versions
  17. 6.00 and 6.00b for MS-DOS.
  18.  
  19. This application note, "Memory Management in QB 4.x," can also be
  20. obtained on paper from Microsoft Product Support Services by calling
  21. (206) 454-2030.
  22.  
  23. A separate article with ENDUSER access describes how customers of
  24. on-line electronic services can obtain the long article below in the
  25. Software/Data Library. This file can be found in the Software/Data
  26. Library by searching on the keyword QB4MEMAN. If you make changes to
  27. this article, the changes also need to be made in the Software
  28. Library.
  29.  
  30. More Information:
  31.  
  32. This application note covers the following topics:
  33.  
  34. 1. Code management
  35.  
  36.    a. Modular programming
  37.  
  38.    b. What goes at the module level in a support module
  39.  
  40.    c. COMMON, COMMON SHARED, SHARED, DIM SHARED
  41.  
  42. 2. Data management
  43.  
  44.    a. $DYNAMIC and $STATIC metacommands
  45.  
  46.    b. Huge arrays
  47.  
  48. Appendix A contains a code example to illustrate the topics covered in
  49. this application note.
  50.  
  51. Appendix B explains the .MAP file created when the Appendix A program
  52. example is linked. You can use the LINK map to determine how close
  53. each module is to approaching the 64K code limit and how close the
  54. .EXE program's static variables are getting to the 64K limit in the
  55. DGROUP.
  56.  
  57. Appendixes C and D describe in detail the memory mapping for running
  58. programs in the following three different environments: the QB.EXE
  59. editor, a compiled .EXE program using the run-time module, and an .EXE
  60. compiled with the stand-alone option.
  61.  
  62. Definitions
  63. -----------
  64.  
  65. A "module" is defined as an individual source file containing BASIC
  66. procedures.
  67.  
  68. "Module-level code" is defined as the statements within a module that
  69. are outside a SUB...END SUB, FUNCTION...END FUNCTION, or DEF FN..END
  70. DEF definition block.
  71.  
  72. A "support module" is a source file, separate from the main module,
  73. that contains additional SUB or FUNCTION procedures.
  74.  
  75. Memory Diagram
  76. --------------
  77.  
  78. The following diagram summarizes how QuickBASIC compiled programs are
  79. loaded into memory at run time:
  80.  
  81.           High Memory (640K maximum)
  82.          _____________
  83.          |           |   The far heap stores dynamic arrays. The far
  84.          |   (Far)   |     heap consists of the rest of high memory
  85.          |   Heap    |     available after MS-DOS and the BASIC
  86.          |           |     program's DGROUP segment and code
  87.    __________________|     segment(s) are allocated.
  88.          |           |   The stack is used to store temporary data,
  89.    DGROUP|   Stack   |     such as variables that are passed to a
  90.          |           |     subprogram procedure. The default stack
  91.    Up to |___________|     size is 2K.
  92.    64K   |           |   The DGROUP (default data segment) is used
  93.          |  (Near)   |     to store all static arrays, strings,
  94.          |   Data    |     simple variables, and the stack. DGROUP
  95.    ___________________     can be up to 64K in size.
  96.                :
  97.          _____________
  98.          |    Code   |   The code segments store the executable code.
  99.          |  Segments |     Each module can have up to 64K for its
  100.          _____________     code segment.
  101.           Low Memory
  102.  
  103.  
  104. Code Management
  105. ---------------
  106.  
  107. Modular Programming
  108. -------------------
  109.  
  110. Modular programming deals with splitting programs into separate
  111. modules (i.e., separate source files containing SUB or FUNCTION
  112. procedures). The reasons for doing this are the following:
  113.  
  114. 1. Once you have written a block of code as a module it can easily be
  115.    incorporated into future projects.
  116.  
  117. 2. Debugging is easier. Problems can be located much more quickly and
  118.    can be contained in a specific area of the program.
  119.  
  120. 3. The compiler (BC.EXE) and the environment (QB.EXE) have a 64K
  121.    code limitation per module. A modular style of programming
  122.    allows you to create programs larger than 64K, since every module,
  123.    even though it is part of one program, can be up to 64K in size.
  124.  
  125. If a program is large, it may be necessary to break it up into several
  126. modules. This is easily accomplished by breaking SUB or FUNCTION
  127. procedures out of the main module and placing them in support modules.
  128. These modules are then compiled separately with BC.EXE and LINKed with
  129. the main module as in the following example.
  130.  
  131. Consider a program Main.BAS which is broken into three modules:
  132.  
  133. 1. MAIN.BAS (which calls external procedures)
  134.  
  135. 2. MODULE2.BAS (which contains SUB and/or FUNCTION procedures)
  136.  
  137. 3. MODULE3.BAS (which contains SUB and/or FUNCTION procedures)
  138.  
  139. The three modules are then each compiled separately to produce the
  140. following object files:
  141.  
  142. 1. BC MAIN.BAS;    ---->  MAIN.OBJ
  143.  
  144. 2. BC MODULE2.BAS; ---->  MODULE2.OBJ
  145.  
  146. 3. BC MODULE3.BAS; ---->  MODULE3.OBJ
  147.  
  148. To produce the executable (.EXE) program, the following command line
  149. is used:
  150.  
  151.     LINK Main.OBJ+Module2.OBJ+Module3.OBJ; ---->  Main.EXE
  152.  
  153. Main.EXE is the finished executable program. When you compile in
  154. QuickBASIC's environment (QB.EXE), the environment automatically
  155. compiles each module and LINKs them together to produce the same .OBJ
  156. files and finished executable program.
  157.  
  158. To make an .EXE program from the QB.EXE environment, do the following:
  159.  
  160. 1. Choose the Run menu.
  161.  
  162. 2. Choose the Make EXE File... option.
  163.  
  164. 3. Choose the Stand-Alone EXE File option to create a stand-alone
  165.    file. If this option is not selected, the program requires
  166.    that the BRUN4x.EXE run-time module be present at run time.
  167.  
  168. 4. Press the ENTER key.
  169.  
  170. The QuickBASIC environment gives you an easy way to do the following
  171. operations, which are described further below:
  172.  
  173. 1. Create a new Module for SUBs
  174.  
  175. 2. Edit SUBs and Modules
  176.  
  177. 3. Delete SUBs
  178.  
  179. 4. Move SUBs from one Module to another Module
  180.  
  181. In QB.EXE, to create a separate module (source file) for SUBs, do the
  182. following:
  183.  
  184. 1. Choose the File menu.
  185.  
  186. 2. Choose the Create File... option.
  187.  
  188. 3. Enter the name for the module.
  189.  
  190. 4. Press the ENTER key.
  191.  
  192. A file will then be created with the name you specified, and it will
  193. be in memory with the other module(s). To save all of the loaded
  194. modules, do the following:
  195.  
  196. 1. Choose the File menu.
  197.  
  198. 2. Choose the Save All option.
  199.  
  200. When the modules are saved together, QuickBASIC creates a file (with
  201. the extension .MAK) that keeps track of the main module and the other
  202. modules that are used by the main. To load all the modules in at once,
  203. do the following:
  204.  
  205. 1. Choose the File menu.
  206.  
  207. 2. Choose the Open Program... option.
  208.  
  209. 3. Select the main module of program as the file to be opened.
  210.  
  211. To view and select SUBs for editing, do the following:
  212.  
  213. 1. Choose the View menu.
  214.  
  215. 2. Choose the SUBs... option.
  216.  
  217. 3. Highlight the module or SUB that you want to edit.
  218.  
  219. 4. Tab down to Edit in Active, or Edit in Split.
  220.  
  221. 5. Press the ENTER key.
  222.  
  223. To delete a SUB, do the following:
  224.  
  225. 1. Choose the View menu.
  226.  
  227. 2. Choose the SUBs... option.
  228.  
  229. 3. Highlight the SUB you want to delete.
  230.  
  231. 4. Tab down to the Delete option.
  232.  
  233. 5. Press the ENTER key.
  234.  
  235. To move a SUB to a different module, do the following:
  236.  
  237. 1. Choose the View menu.
  238.  
  239. 2. Choose the SUBS... option.
  240.  
  241. 3. Highlight the SUB you want to move.
  242.  
  243. 4. Tab down to the Move option.
  244.  
  245. 5. Press the ENTER key.
  246.  
  247. 6. Select the module you want the SUB to be in.
  248.  
  249. 7. Press the ENTER key.
  250.  
  251. More information about using the QB.EXE environment can be found in
  252. the "Microsoft QuickBASIC: Learning to Use" manual for Version 4.50,
  253. or in the "Microsoft QuickBASIC 4.0: Learning and Using" manual for
  254. Versions 4.00 and 4.00b and the BASIC compiler Versions 6.00 and
  255. 6.00b.
  256.  
  257. What Goes at the Module Level in a Support Module
  258. -------------------------------------------------
  259.  
  260. A support module, when compiled, produces an object (.OBJ) file that
  261. is LINKed with a main module to create an executable file. The
  262. module-level code of the main module is the only code directly
  263. executed by QuickBASIC. The module-level code of the support modules
  264. cannot be CALLed, RUN, or CHAINed. This module-level code of the
  265. support modules is used only for the following:
  266.  
  267. 1. Event- or error-trapping handlers
  268.  
  269. 2. Metacommands
  270.  
  271. 3. TYPE definitions, DIM, and COMMON SHARED statements
  272.  
  273. You can place ON Event GOSUB and ON ERROR GOTO trapping statements
  274. within SUBprogram procedures [where ON Event means ON KEY(n), ON
  275. COM(n), ON TIMER(n), etc.]. However, the line or line label that is
  276. the target of the event or error trap's GOTO or GOSUB must be at the
  277. module-level code in the same module as that SUBprogram. This is
  278. because QuickBASIC doesn't allow GOSUBs or GOTOs from a SUBprogram to
  279. other modules or SUBprograms, and QuickBASIC allows only ON Event
  280. GOSUB and ON ERROR GOTO statements to jump from a SUBprogram to the
  281. module-level code.
  282.  
  283. The compiler metacommands (REM $INCLUDE, REM $STATIC, and REM
  284. $DYNAMIC) can also be used at the module level. REM $INCLUDE pastes
  285. extra source into the module at compile time. REM $DYNAMIC and REM
  286. $STATIC declare subsequent arrays as $DYNAMIC (allocated at run time)
  287. or $STATIC (allocated at compile time).
  288.  
  289. You can use TYPE...END TYPE, DIM, and COMMON SHARED statements in the
  290. module-level code. Variables and arrays can be shared between modules
  291. using the COMMON SHARED statement at the module level.
  292.  
  293. COMMON, COMMON SHARED, SHARED, and DIM SHARED
  294. ---------------------------------------------
  295.  
  296. The SHARED statement gives a SUB or FUNCTION procedure access to
  297. variables declared at the main module level of that module (without
  298. passing them as parameters). It does NOT give access to variables
  299. declared in support modules.
  300.  
  301. The COMMON statement makes variables available at the module level
  302. between modules. The SHARED attribute for the COMMON statement (i.e.,
  303. COMMON SHARED) is required to share the variables with SUBprograms or
  304. FUNCTIONs. The list of variables in the COMMON and COMMON SHARED
  305. statements must match in type in the COMMON and COMMON SHARED
  306. statements in each module.
  307.  
  308. When using the COMMON (or COMMON SHARED) statement, static and dynamic
  309. arrays are dimensioned differently. Static arrays in COMMON must be
  310. DIMensioned BEFORE the COMMON statement in all the modules with that
  311. COMMON statement. Dynamic arrays in COMMON must be DIMensioned AFTER
  312. the COMMON statement in just the main module and should not be
  313. DIMensioned in any support modules.
  314.  
  315. There are two differences between using the SHARED statement and the
  316. DIM SHARED statement:
  317.  
  318. 1. To make a variable accessible by all the SUBprograms in a module,
  319.    use DIM SHARED at the module level.
  320.  
  321. 2. To share a module level variable with a specific SUBprogram, put
  322.    the variable in a SHARED statement in the SUBprogram. The SHARED
  323.    statement goes directly after the first line of the SUBprogram.
  324.  
  325. Data Management
  326. ---------------
  327.  
  328. $DYNAMIC and $STATIC Arrays
  329. ---------------------------
  330.  
  331. The default setting for storing arrays is REM $STATIC, which stores
  332. all arrays in DGROUP (the default data segment). For any BASIC .EXE
  333. program, DGROUP is limited to 64K. If you are using static arrays, you
  334. can get more memory in DGROUP by making the arrays dynamic, which
  335. moves them into the far heap. To make an array dynamic, DIMension the
  336. array after the metacommand REM $DYNAMIC, or DIMension the array with
  337. a variable in its subscript.
  338.  
  339. All dynamic arrays are stored on the far heap except arrays of
  340. variable-length strings. Strings, variable-length string arrays, and
  341. simple variables are always stored in DGROUP. To store strings in the
  342. far heap, you must DIMension a dynamic array of fixed-length strings.
  343. DIMensioning strings as fixed length in dynamic arrays helps to free
  344. up storage space that they otherwise could have taken in DGROUP, which
  345. is limited to 64K.
  346.  
  347. Huge Arrays
  348. -----------
  349.  
  350. Huge arrays are arrays that are larger than 64K. When using huge
  351. arrays, you must invoke the QB.EXE editor and BC.EXE compiler with the
  352. /AH option. The huge array must be DIMensioned as a dynamic array,
  353. either with the metacommand REM $DYNAMIC or with a variable in the
  354. array subscript. The /AH option allows dynamic arrays of user-defined
  355. types, fixed-length strings, and numeric data to occupy all of
  356. available memory.
  357.  
  358. The number of bytes in a single element of a huge array should be a
  359. power of 2 because space is allocated for huge arrays in 64K segments.
  360. If a record size is not a power of 2, a "gap" appears between the
  361. allocated segments that is wasted, unused memory. The gap occurs
  362. because an array element is not allowed to span across a 64K segment
  363. boundary, so that element is moved up to the start of that boundary.
  364. QuickBASIC allows only one gap to appear in a program. A "Subscript
  365. out of Range" error occurs when allocating a huge array larger than
  366. 128K if gaps occur.
  367.  
  368. The final major aspect of QuickBASIC memory management is that
  369. QuickBASIC attempts to make the most efficient use of memory possible,
  370. which may cause variable-length strings, variable-length string
  371. arrays, and dynamic arrays to move around in memory from statement to
  372. statement at run time. (All other variables have a fixed location
  373. determined at load time.) Because of this, the results of the VARPTR,
  374. VARSEG, VARPTR$, or SADD function should be used immediately after
  375. that function is invoked.
  376.  
  377. Appendix A: Sample Program
  378. --------------------------
  379.  
  380. This sample program demonstrates the topics covered in this
  381. application note. This program gives an example of ways to DIMension
  382. arrays, and to pass variables between modules and SUBprograms. The
  383. program consists of two modules, each which defines one SUBprogram.
  384.  
  385. Main Module (EXAMPL1.BAS)
  386. -------------------------
  387.  
  388. DECLARE SUB OtherModSub ()
  389. DECLARE SUB Subdemo ()
  390.  
  391. TYPE PowerOfTwo
  392.      I  AS INTEGER             ' 2  Bytes
  393.      L  AS LONG                ' 4  Bytes
  394.      S  AS SINGLE              ' 4  Bytes
  395.      D  AS DOUBLE              ' 8  Bytes
  396.      St AS STRING * 14         ' 14 Bytes
  397. END TYPE                       ' 32 Bytes Total, a power of 2, 2^5
  398.  
  399. REM $STATIC
  400. DIM A(100) AS INTEGER          ' Static array, stored in DGROUP.
  401.  
  402. COMMON SHARED A() AS INTEGER   ' Share the variables with the other
  403. COMMON SHARED B AS STRING * 20 '  module and its SUBprograms.
  404. COMMON SHARED X() AS INTEGER
  405.  
  406. REM $DYNAMIC
  407. DIM X(100) AS INTEGER         ' Dynamic array, stored in far heap.
  408. DIM PTwo(4000) AS PowerOfTwo  ' Dynamic huge array, stored in far heap
  409.                               '  Each element is a power of two, 2^5.
  410.  
  411. DIM NonFixedLen(10) AS STRING ' Dynamic array, but since it is not
  412.                               '  fixed length it is stored in DGROUP.
  413.  
  414. REM $STATIC
  415. DIM SHARED M(100) AS LONG        ' These variables are shared with all
  416. DIM SHARED Equals AS STRING * 10 '  the SUBprograms in this module,
  417.                                  '  and are stored in the DGROUP.
  418. Num = 40
  419.  
  420. DIM DynArray(Num) AS SINGLE   ' The array is dynamic since it is
  421.                               '  DIMensioned with a variable, so
  422.                               '  it is stored in far heap.
  423. Plus$ = " + "
  424. Equals = " = "
  425. M(1) = 7
  426. A(1) = 4
  427.  
  428. CALL Subdemo             ' CALLs the SUBprogram of this module.
  429. CALL OtherModSub         ' CALLs the SUBprogram of the support module.
  430. END
  431.  
  432. 'SUBprogram of the Main Module:
  433.  
  434. SUB Subdemo
  435. SHARED Plus$, NonFixedLen() AS STRING, Num
  436.     PRINT STR$(Num) + Plus$;
  437.     PRINT STR$(M(1))+ Equals + STR$(A(1));
  438.     A(1) = M(1)
  439. END SUB
  440.  
  441.  
  442. Support Module (EXAMPL2.BAS)
  443. ----------------------------
  444.  
  445. REM $STATIC
  446.  
  447. DIM A(100) AS INTEGER          ' Only the static array is DIMensioned
  448. COMMON SHARED A() AS INTEGER   '  before the COMMON SHARED statement.
  449. COMMON SHARED B AS STRING * 20
  450. COMMON SHARED X() AS INTEGER   ' The dynamic array is only DIMensioned
  451.                                '  in the main module.
  452.  
  453. Panic:                         ' The label for ON ERROR has to be at
  454.      resume next               '  the module level.
  455.  
  456. ' SUBprogram of the Support Module:
  457.  
  458. SUB OtherModSub
  459.     PRINT A(1)
  460.     ON ERROR Panic
  461. END SUB
  462.  
  463. Appendix B: Link .MAP File Explanation
  464. --------------------------------------
  465.  
  466. Below is a .MAP file created when the program example in Appendix A
  467. is linked. The .MAP file from a successful link shows how close a
  468. module's code segment is approaching the 64K code limit, and how
  469. close the static variables for the entire .EXE program are to
  470. approaching the 64K limit in the DGROUP. To generate a listing map of
  471. a program, include a map filename in the third argument of the LINK
  472. command, as in the following example:
  473.  
  474.    LINK EXAMPL1.OBJ+EXAMPL2.OBJ,,EXAMPLE.MAP;
  475.  
  476. Notes for the link .MAP shown further below are as follows:
  477.  
  478. 1. EXAMPL1_CODE is the code segment for EXAMPL1.BAS.
  479.  
  480. 2. EXAMPL2_CODE is the code segment for EXAMPL2.BAS.
  481.  
  482. 3. The code segment of each module has to be less than 64K. When the
  483.    code segment is getting close to 64K, break the module into two or
  484.    more modules. To find the length of a code segment, look under the
  485.    Length column. For example, the length of the code segment for
  486.    EXAMPL1.BAS is 15A hex bytes, which is 346 in decimal notation.
  487.  
  488. 4. FAR_MSG is the far management group that holds text of error
  489.    messages. This is NOT the far heap. The far heap is allocated at
  490.    run-time.
  491.  
  492. 5. According to the Origin section at the bottom of the link map,
  493.    DGROUP starts at 06DC:0, which is the paragraph address 06DC
  494.    hex, with an offset of 0. This is the same as the byte address
  495.    06DC0 hex (since a paragraph contains 16 bytes). Thus, in this
  496.    example, DGROUP starts where BR_DATA starts.
  497.  
  498. 6. DGROUP ends at the Stop address of the STACK.
  499.  
  500. 7. To find out how large the program's DGROUP is, take the Stop
  501.    address of the stack and subtract from it the Start address of
  502.    first data element in the DGROUP. For example, the size of the
  503.    program's DGROUP is 7F9F hex minus 6DC0 hex, which equals 11DF hex
  504.    (4575) bytes.
  505.  
  506. 8. All addresses in the .MAP are only relative to the start of the
  507.    .EXE program. The absolute load address is determined by DOS only
  508.    at run time. The VARSEG and VARPTR statements can be used in your
  509.    program at run time to display the absolute addresses of the
  510.    variables.
  511.  
  512. EXAMPLE.MAP
  513. -----------
  514.  
  515.  Start  Stop   Length Name                   Class
  516.  00000H 00159H 0015AH EXAMPL1_CODE           BC_CODE
  517.  00160H 001C1H 00062H EXAMPL2_CODE           BC_CODE
  518.  001C2H 03931H 03770H CODE                   CODE
  519.  03932H 03A0CH 000DBH INIT_CODE              CODE
  520.  03A10H 041B2H 007A3H _TEXT                  CODE
  521.  041C0H 065EFH 02430H EMULATOR_TEXT          CODE
  522.  065F0H 065F0H 00000H C_ETEXT                ENDCODE
  523.  065F0H 065F7H 00008H FAR_HDR                FAR_MSG
  524.  065F8H 06C44H 0064DH FAR_MSG                FAR_MSG
  525.  06C45H 06C46H 00002H FAR_PAD                FAR_MSG
  526.  06C47H 06C47H 00001H FAR_EPAD               FAR_MSG
  527.  06C50H 06DBFH 00170H EMULATOR_DATA          FAR_DATA
  528.  
  529.  06DC0H 06DC0H 00000H BR_DATA                BLANK
  530.  06DC0H 06DEFH 00030H BR_SKYS                BLANK
  531.  06DF0H 06EFBH 0010CH COMMON                 BLANK
  532.  06EFCH 070E3H 001E8H BC_DATA                BC_VARS
  533.  070E4H 070E9H 00006H NMALLOC                BC_VARS
  534.  070EAH 070EAH 00000H ENMALLOC               BC_VARS
  535.  070EAH 070EAH 00000H BC_FT                  BC_SEGS
  536.  070F0H 0710FH 00020H BC_CN                  BC_SEGS
  537.  07110H 07122H 00013H BC_DS                  BC_SEGS
  538.  07124H 07124H 00000H BC_SAB                 BC_SEGS
  539.  07124H 0712BH 00008H BC_SA                  BC_SEGS
  540.  0712CH 0712FH 00004H BC_SAE                 BC_SEGS
  541.  07130H 07345H 00216H _DATA                  DATA
  542.  07346H 0761FH 002DAH _BSS                   DATA
  543.  07620H 0771CH 000FDH BR_DATA                DATA
  544.  0771EH 0771EH 00000H XIB                    DATA
  545.  0771EH 07741H 00024H XI                     DATA
  546.  07742H 07742H 00000H XIE                    DATA
  547.  07742H 0774DH 0000CH DBDATA                 DATA
  548.  0774EH 0775BH 0000EH CDATA                  DATA
  549.  0775CH 0775CH 00000H XIFB                   DATA
  550.  0775CH 0775CH 00000H XIF                    DATA
  551.  0775CH 0775CH 00000H XIFE                   DATA
  552.  0775CH 0775CH 00000H XPB                    DATA
  553.  0775CH 0775CH 00000H XP                     DATA
  554.  0775CH 0775CH 00000H XPE                    DATA
  555.  0775CH 0775CH 00000H XCB                    DATA
  556.  0775CH 0775FH 00004H XC                     DATA
  557.  07760H 07760H 00000H XCE                    DATA
  558.  07760H 07760H 00000H XCFB                   DATA
  559.  07760H 07760H 00000H XCF                    DATA
  560.  07760H 07760H 00000H XCFE                   DATA
  561.  07760H 0779FH 00040H CONST                  DATA
  562.  077A0H 077A0H 00000H BC_DATA                BC_DATA
  563.  077A0H 077A0H 00000H XOB                    BSS
  564.  077A0H 077A0H 00000H XO                     BSS
  565.  077A0H 077A0H 00000H XOE                    BSS
  566.  077A0H 07F9FH 00800H STACK                  STACK
  567.  
  568.  Origin   Group
  569.  06DC:0   DGROUP
  570.  065F:0   FMGROUP
  571. Program entry point at 03A1:00C8
  572.  
  573.  
  574. Appendix C: Where QuickBASIC 4.00, 4.00b, and 4.50 Stores Their Arrays
  575. ----------------------------------------------------------------------
  576.  
  577. There is one difference in array storage between programs run as
  578. compiled .EXE files and programs run within the QuickBASIC Versions
  579. 4.00, 4.00b, and 4.50 environment (QB.EXE). In the QB.EXE environment,
  580. an array that is static, not in COMMON, and not composed of
  581. variable-length strings, is stored in the far heap (instead of DGROUP,
  582. as in .EXE programs).
  583.  
  584. This changes memory management in your program, depending on where
  585. you run your program.
  586.  
  587. Thus, in programs run within the QuickBASIC 4.00, 4.00b, or 4.50
  588. environment (QB.EXE), arrays are stored as follows:
  589.  
  590. 1. All $STATIC arrays in COMMON are stored in DGROUP and can be
  591.    referenced with near addresses.
  592.  
  593. 2. All arrays of variable-length strings are also stored in DGROUP and
  594.    can also be referenced with near addresses.
  595.  
  596. 3. All other arrays are stored as far objects and require far
  597.    addresses. This includes $STATIC arrays that are not in a COMMON
  598.    statement, and these arrays can move in memory like $DYNAMIC arrays.
  599.  
  600. In QuickBASIC 4.00, 4.00b, and 4.50 programs that are run as compiled
  601. .EXE files, arrays are stored as follows:
  602.  
  603. 1. All $STATIC arrays are stored in DGROUP and can be referenced with
  604.    near addresses.
  605.  
  606. 2. All $DYNAMIC arrays of variable-length strings are also stored in
  607.    DGROUP and can also be referenced with near addresses.
  608.  
  609. 3. All other $DYNAMIC arrays are stored as far objects.
  610.  
  611. Appendix D: Memory Maps
  612. -----------------------
  613.  
  614. This appendix contains illustrations of three different run-time
  615. memory maps.
  616.  
  617. Figure 1
  618. --------
  619. The first figure (below) shows the run-time memory map when the
  620. program is executed within the QB.EXE Version 4.x environment:
  621.  
  622.                    _______________
  623.                    |    Quick    |
  624.                    |   Library   |
  625.                    |_____________|
  626.                    |Communication|  User-specified size
  627.                    |   buffers   |
  628.                    |_____________|
  629.                    |             |  This area contains items, such as
  630.                    |   FAR heap  |    large/huge arrays and user code,
  631.                    |             |    dynamic arrays.
  632.                    |_____________|
  633. User Data  ------->|Run-time heap|  Files buffers, etc.
  634. End DS:xxxx        |_____________|
  635.                    | String heap |
  636.                    |_____________|
  637.                    | User Program|
  638. DGROUP             |    Data     |
  639.                    |_____________|
  640. UP to              |  User Stack |
  641. 64K                |_____________|
  642.                    |  Quick Lib  |
  643.                    |    Data     |
  644.                    |_____________|
  645.                    |  QuickBASIC |
  646. User Data          |   Static    |
  647. Start DS:0 ------->|    Data     |
  648.                    |_____________|
  649.                    |  QuickBASIC |  QB.EXE
  650. Low Memory ------->|    Code     |
  651.                    |_____________|
  652.                    |    MS-DOS   |  MS-DOS Operating System
  653.                    _______________
  654. 0000:0000  ------->
  655.  
  656. Figure 1 (above): The Memory Map for QB.EXE 4.x Environment
  657.  
  658.  
  659. Figure 2
  660. --------
  661. This second figure (below) shows the run-time memory map as it appears
  662. when the run-time module BRUN4x.EXE is used with the separate
  663. compilation (Make EXE File...) method:
  664.  
  665.                    _______________
  666.                    | BRUN4x.EXE  |  Separately loaded run-time code
  667.                    |_____________|
  668.                    |Communication|  User-specified size
  669.                    |   buffers   |
  670.                    |_____________|
  671.                    |             |  This area holds less-frequently-
  672.                    |             |     used items, such as dynamic
  673.                    |   FAR heap  |     arrays, the user environment
  674.                    |             |     table.
  675.                    |             |
  676.                    |             |
  677.                    |_____________|
  678. User Data  ------->|Run-time heap|
  679. End DS:xxxx        |_____________|
  680.                    | String heap |
  681.                    |_____________|
  682.                    |  User Stack |  Preset to 2K
  683.                    |_____________|
  684.                    |    Named    |  Named COMMON areas
  685.                    |    COMMON   |
  686. DGROUP             |_____________|
  687.                    |   BC_DATA   |  User program variables
  688. Up to              |_____________|
  689. 64K                |   BC_CONST  |  User program constants
  690.                    |_____________|
  691.                    | Blank COMMON|
  692.                    |_____________|
  693.                    |   _DATA     |  QuickBASIC run-time data areas,
  694. User Data          |    CONST    |     used during user code execution
  695. Start DS:0 ------->|   _BSS      |
  696.                    |_____________|
  697.                    |  User Code  |  User program separately linked
  698. Low Memory ------->|             |     with BRUN4x.LIB
  699.                    |_____________|
  700.                    |    MS-DOS   |  MS-DOS Operating System
  701.                    _______________
  702. 0000:0000  ------->
  703.  
  704. Figure 2 (above): The BRUN4x.EXE Run-Time Module Memory for an .EXE
  705.  
  706.  
  707. Figure 3
  708. --------
  709. This third figure (below) shows the run-time memory map when the
  710. stand-alone library (BCOM4x.LIB) option is used with the separate
  711. compilation (Make EXE File...) method:
  712.  
  713.                    _______________
  714.                    |Communication|  User specified size
  715.                    |   buffers   |
  716.                    |_____________|
  717.                    |             |  This area contains less frequently
  718.                    |             |     used items, such as large
  719.                    |   FAR heap  |     numeric arrays, the user
  720.                    |             |     environment table, dynamic
  721.                    |             |     arrays.
  722.                    |             |
  723.                    |_____________|
  724. User Data  ------->|Run-time heap|  Files buffers, etc.
  725. End DS:xxxx        |_____________|
  726.                    | String heap |
  727.                    |_____________|
  728.                    |  User Stack |  Preset to 2K bytes
  729.                    |_____________|
  730.                    |    Named    |  Named COMMON areas
  731.                    |    COMMON   |
  732. DGROUP             |_____________|
  733.                    |   BC_DATA   |  User program variables
  734. Up to              |_____________|
  735. 64K                |   BC_CONST  |  User program constants
  736.                    |_____________|
  737.                    | Blank COMMON|  Library and user definitions
  738.                    |_____________|
  739.                    |   _DATA     |  QuickBASIC run-time data areas,
  740. User Data          |    CONST    |     used during user code execution
  741. Start DS:0 ------->|   _BSS      |
  742.                    |_____________|
  743.                    |Run-time code|  Run-time code linked into file
  744.                    |_____________|
  745.                    |  User Code  |  User program separately linked
  746. Low Memory ------->|             |     with BCOM4x.LIB
  747.                    |_____________|
  748.                    |    MS-DOS   |  MS-DOS Operating System
  749.                    _______________
  750. 0000:0000  ------->
  751.  
  752. Figure 3 (above): The Stand-Alone (BCOM4x.LIB Library) Memory for
  753.                   an .EXE
  754.