📄 spdos.gml
字号:
It is possible to place overlays in separate files by specifying
the "INTO" option in the "SECTION" directive that starts the definition
of an overlay.
By specifying the "INTO" option in the "AUTOSECTION" directive, all overlays
created as a result of the "AUTOSECTION" directive are placed in one overlay
file.
.np
Consider the following example.
It is similar to the previous example except for the following.
Overlay #1 is placed in the file "ovl1.ovl", overlay #2 is placed in the
file "ovl2.ovl", overlay #3 is placed in the file "ovl3.ovl" and overlays
#4, #5 and #6 are placed in file "ovl4.ovl".
.millust begin
#
# Define files that belong in the root.
#
file file0, file1
#
# Define an overlay area.
#
begin
section into ovl1 file file2
section into ovl2 file file3, file4
section into ovl3 file file5
end
#
# Define an overlay area.
#
begin
autosection into ovl4
file file6
file file7
file file8
end
.millust end
.*
.beglevel
.*
.section The Dynamic Overlay Manager
.*
.np
Let us again consider the above example but this time we will use the
dynamic overlay manager.
The easiest way to take the above overlay structure and use it with
the dynamic overlay manager is to simply specify the "DYNAMIC" option.
.millust begin
option DYNAMIC
.millust end
.pc
Even though we have defined an overlay structure with more than one
overlay area, the &lnkname will allocate one overlay area and overlays
from both overlay areas will be loaded into a single overlay area.
The size of the overlay area created by the &lnkname will be twice the size
of the largest overlay area (unless the "AREA" option is used).
.np
To take full advantage of the dynamic overlay manager, the following sequence
of directives should be used.
.millust begin
#
# Define files that belong in the root.
#
file file0, file1
#
# Define an overlay area.
#
begin
autosection into ovl1
file file2
autosection into ovl2
file file3
file file4
autosection into ovl3
file file5
autosection into ovl4
file file6
file file7
file file8
end
.millust end
.np
In the above example, each module will be in its own overlay.
This will result in a module being loaded into memory only when it is required.
If separate overlay files are not required, a single "AUTOSECTION" directive
could be used as demonstrated by the following example.
.millust begin
#
# Define files that belong in the root.
#
file file0, file1
#
# Define an overlay area.
#
begin
autosection
file file2
file file3
file file4
file file5
file file6
file file7
file file8
end
.millust end
.*
.endlevel
.*
.section Nested Overlay Structures
.*
.np
Nested overlay structures occur when the "BEGIN"-"END" directives
are nested and are only useful if the standard overlay manager is being used.
If you have selected the dynamic overlay manager, the nesting levels will be
ignored and each overlay will be loaded into a single overlay area.
.np
Consider the following directive file.
.millust begin
#
# Define files that belong in the root.
#
file file0, file1
#
# Define a nested overlay structure.
#
begin
section file file2
section file file3
begin
section file file4, file5
section file file6
end
end
.millust end
.autonote Notes:
.note
The root contains
.id file0
and
.id file1.
.note
Four overlays are defined.
The first overlay (overlay #1) contains
.id file2,
the second overlay (overlay #2) contains
.id file3,
the third overlay (overlay #3) contains
.id file4
and
.id file5,
and the fourth overlay (overlay #4) contains
.id file6.
.endnote
.np
The following diagram depicts the overlay structure.
:cmt. :set symbol='c0' value=&sysin+4
:cmt. :set symbol='c1' value=&c0+18
:cmt. :set symbol='c2' value=&c1+9
:cmt. :set symbol='c3' value=&c2+9
:cmt. .tb set `
:cmt. .tb &c0+1 &c0+7 &c1-1 &c1+1 &c1+4 &c2-1 &c2+1 &c2+4 &c3+2
:cmt. .bx &c0 &c3
:cmt. ``file0`````\{ start of root
:cmt. ``file1
:cmt. .bx &c0 &c1 &c3
:cmt. #1```#2`````\{ start of overlay area
:cmt.
:cmt. `file2````file3
:cmt.
:cmt.
:cmt. .bx new &c0 / &c1 &c2 &c3
:cmt. ```#3`file4``#4`file6
:cmt. ````file5
:cmt. .bx can
:cmt. .bx off &c0 &c1 &c2 &c3
.millust begin
+-----------------------------------+<- start of root
| |
| file0 |
| file1 |
| |
+-----------+-----------------------+<- start of overlay
| #1 | #2 | area
| | |
| file2 | file3 |
| | |
| | |
| +-----------+-----------+<- start of overlay
| | #3 | #4 | area
| | | |
| | file4 | file6 |
| | file5 | |
| | | |
+-----------+-----------+-----------+
.millust end
.autonote Notes:
.note
Overlay #1 and overlay #2 are parallel overlays.
Overlay #3 and overlay #4 are also parallel overlays.
.note
Overlay #3 and overlay #4 are loaded in memory following overlay #2.
In this case, overlay #2 is called an
.ix 'overlay' 'ancestor of'
.us ancestor
of overlay #3 and overlay #4.
Conversely, overlay #3 and overlay #4 are
.ix 'overlay' 'descendant of'
.us descendants
of overlay #2.
.note
The root is an ancestor of all overlays.
.endnote
.np
Nested overlays are particularly useful when the routines that make
up one overlay are used only by a few other overlays.
In the above example, the routines in overlay #2 would only be used
by routines in overlay #3 and overlay #4 but not by overlay #1.
.*
.section Rules About Overlays
.*
.np
The &lnkname handles all the details of loading overlays.
No changes to a program have to be made if, for example, it becomes
so large that you have to change to an overlay structure.
Certain rules have to be followed to ensure the proper execution of
your program.
These rules pertain more to the organization of the components of your
program and less to the way it was coded.
.autonote
.note
Care should be taken when passing addresses of functions as arguments.
Consider the following example.
.millust begin
+-----------------------+<- start of root
| |
| main |
| |
+-----------+-----------+<- start of overlay
| modulea | moduleb | area
| | |
| f | h |
| g | |
| | |
+-----------+-----------+
.millust end
.np
Function
.sy f
passes the address of
.us static
function
.sy g
to function
.sy h.
Function
.sy h
then calls function
.sy g
indirectly.
Function
.sy f
and function
.sy g
are defined in
.sy modulea
and function
.sy h
is defined in
.sy moduleb.
Furthermore, suppose that
.sy modulea
and
.sy moduleb
are parallel overlays.
The linker will not generate an overlay vector for function
.sy g
since it is static so when function
.sy h
calls function
.sy g
indirectly, unpredictable results may occur.
Note that if
.sy g
is a global function, an overlay vector will be generated and the program
will execute correctly.
.note
You should organize the overlay structure to minimize the number of times
overlays have to be loaded into memory.
Consider a loop calling two routines, each routine in a different
overlay.
If the overlay structure is such that the overlays are parallel, that
is they occupy the same memory, each iteration of the loop will cause
2 overlays to be loaded into memory.
This will significantly increase execution time if the loop is
iterated many times.
.note
If a number of overlays have a number of common routines that they
all reference, the common routines will most likely be placed
in an ancestor overlay of the overlays that reference them.
For this reason, whenever an overlay is loaded, all its ancestors
are also loaded.
.note
.ix 'overlay loader'
In an overlayed program, the
.us overlay loader
is included in the executable file.
If we are dealing with relatively small programs, the size of the
overlay loader may be larger than the amount of memory saved by
overlaying the program.
In a larger application, the size of the overlayed version would be
smaller than the size of the non-overlayed version.
Note that overlaying a program results in a larger executable file but
the memory requirements are less.
.note
.ix '__OVLTAB__ linker symbol'
.ix '__OVLSTARTVEC__ linker symbol'
.ix '__OVLENDVEC__ linker symbol'
.ix '__LOVLLDR__ linker symbol'
.ix '__NOVLLDR__ linker symbol'
.ix '__SOVLLDR__ linker symbol'
.ix '__LOVLINIT__ linker symbol'
.ix '__NOVLINIT__ linker symbol'
.ix '__SOVLINIT__ linker symbol'
.ix 'linker symbols' '__OVLTAB__'
.ix 'linker symbols' '__OVLSTARTVEC__'
.ix 'linker symbols' '__OVLENDVEC__'
.ix 'linker symbols' '__LOVLLDR__'
.ix 'linker symbols' '__NOVLLDR__'
.ix 'linker symbols' '__SOVLLDR__'
.ix 'linker symbols' '__LOVLINIT__'
.ix 'linker symbols' '__NOVLINIT__'
.ix 'linker symbols' '__SOVLINIT__'
The symbols "__OVLTAB__", "__OVLSTARTVEC__", "__OVLENDVEC__",
"__LOVLLDR__", "__NOVLLDR__", "__SOVLLDR__",
"__LOVLINIT__", "__NOVLINIT__" and "__SOVLINIT__" are defined
when you use overlays.
Your program should not define these symbols.
.note
When using the dynamic overlay manager, you should not take the
address of static functions.
Static functions are not given overlay vectors, so if the module in
which the address of a static function is taken, is moved by the
dynamic overlay manager, that address will no longer point to the
static function.
.endnote
.*
.section *refid=incover Increasing the Dynamic Overlay Area
.*
.np
.ix 'dynamic overlay manager' 'increasing dynamic overlay area at run-time'
.ix 'overlays' 'increasing dynamic overlay area at run-time'
Unless the "AREA" option has been specified, the default size of the
dynamic overlay area is twice the size of the largest overlay (or
module if each module is its own overlay).
It is possible to add additional overlay areas at run-time so that the
dynamic overlay manager can use the additional memory.
A routine has been provided, called
.id _ovl_addarea.
This function is defined as follows.
.millust begin
void far _ovl_addarea(unsigned segment,unsigned size);
.millust end
.np
The first argument is the segment address of the block memory you wish
to add.
The second argument is the size, in paragraphs, of the memory block.
.np
In assembly language, the function is called
.id _ovl_addarea_
with the first argument being passed in register AX and the second
argument in register DX.
.*
.section How Overlay Files are Opened
.*
.np
The overlay manager normally opens overlay files, including executable
files containing overlays, in compatibility mode.
Compatibility mode is a sharing mode.
A file opened in compatibility mode means that it can be opened any
number of times provided that it is not currently opened under one of
the other sharing modes.
In other words, the file must always be opened in compatibility mode.
.np
The overlay manager keeps most recently used overlay files open for
efficiency.
This means that any application, including the currently executing
application, that may want to open an overlay file, must open it in
compatibility mode.
For example, the executing application may have data at the end of the
executable file that it wishes to access.
.np
If an application wishes to open the file in a sharing mode other than
compatibility mode, the function
.id _ovl_openflags
has been defined which allows the caller to specify the sharing mode
with which the overlay files will be opened by the overlay manager.
This function is defined as follows.
.millust begin
unsigned far _ovl_openflags(unsigned sharing_mode);
.millust end
.np
Legal values for the sharing mode are as follows.
.illust begin
.tb set `
.tb &SYSIN. +15
Sharing Mode`Value
-----------------`-------
compatibility mode`0x00
deny read/write mode`0x01
deny write mode`0x02
deny read mode`0x03
deny none mode`0x04
.tb set
.illust end
.np
The return value is the previous sharing mode used by the overlay
manager to open overlay files.
.np
Note that DOS opens executable files in compatibility mode when
loading them for execution.
This is important for executable files on networks that may be
accessed simultaneously by many users.
.np
In assembly language, the function is called
.id _ovl_openflags_
with its argument being passed in register AX.
.*
.endlevel
.*
.do end
.*
.im ms2wlink
.*
.helppref
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -