Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ОАиП_1 / Module2 / УЭ-8

.html
Скачиваний:
17
Добавлен:
25.02.2016
Размер:
19.36 Кб
Скачать

Документ без названия

Модуль Overlay       При разработке крупных программных систем может возникнуть ситуация, когда общий объем программы будет превышать размер допустимый ОП (64 Кб). Общий объем программы можно увеличить за счет использования модулей, поскольку каждому модулю выделяется в ОП свой сегмент. Это позволяет обойти ограничения на размер программы. Вместе с тем Турбо-Паскаль располагает более гибким и экономичным способом использования ОП ЭВМ для размещения в ней программ. Этот способов заключается в применении оверлеев.    Оверлей - часть программы, которые совместно используют общую область памяти     При этом в каждый момент времени в памяти размещается только часть программы, необходимая для выполнения заданной функции. В процессе работы эти части могут замещаться друг другом. При компиляции таких программ наряду с .exe файлом генерируется оверлейный файл с расширением ovr, который содержит все оверлейные модули, которые при выполнении программы будут, по мере необходимости, подключаться в память. Существует несколько правил для работы с оверлеями: оверлей представляет собой обычный модуль и оформляется по всем правилам построения модуля в начале всех оверлейных модулей должна быть размещена директива компилятора {$ 0+}, которая указывает на то, что данный модуль должен быть откомпилирован как оверлейный процедуры и функции вызывающие оверлейные программы должны быть откомпилированы с директивой компилятора {$ F+} программы, содержащие оверлейные модули, должны компилироваться на диск       Использование оверлеев поддерживается стандартным модулем Overlay, в котором определены следующие константы:     const         OvrOk = 0; {успешное завершение}         OvrError = -1; {ошибка монитора оверлеев}         OvrNotFound = -2; {файл оверлеев не найден}         OvrNoMemory = -3; {нет памяти для буфера}         OvrIoError = -4; {ошибка ввода-вывода при загрузке оверлеев}         OvrNoEMSDriver = -5; {драйвер EMS не установлен}         OvrNoEMSMemory = -6; {недостаточно памяти для EMS}       Рассмотрим основные процедуры модуля: ПроцедураНазначение OvrInit (FileName: string)       Инициализирует подсистему управления оверлеями и открывает оверлейный файл. Его имя FileName задается в виде:                   'диск: \ каталог \ … \ подкаталог \ имя.ovr'       Если в параметре FileName не задан накопитель или каталог, то оверлейный файл будет создан в текущем каталоге. При дальнейшем выполнении программы поиск оверлейного файла производиться сначала в текущем каталоге, затем – в каталоге, который содержит exe-файлы и т.д.       Ошибка выполнения данной процедуры возвращается в переменную OvrResult. Если OvrResult 0, то любая попытка вызова оверлейной программы приведет к ошибке выполнения. Процедура OvrInit должна вызываться перед вызовом любой другой процедуры, использующей оверлеи. OvrGetBuf: longint       Возвращает текущий размер оверлейного буфера OvrSetBuf (BufSize: longint)       Устанавливает размер оверлейного буфера OvrClearBuf       Очищает оверлейный буфер и вызывает перезагрузку оверлеев       Как же работает программа, использующая оверлеи??       Когда программа компилируется, все оверлейные модули помещаются в соответствующий ovr-файл. При выполнении программы оверлеи из ovr-файла по мере необходимости загружаются в оверлейный буфер, который располагается в оперативной памяти между стеком и динамической областью. Размер оверлейного буфера по умолчанию устанавливается таким, чтобы в нем мог разместиться по меньшей мере один оверлей наибольшего размера. В процессе работы программы размер оверлейного буфера может быть увеличен за счет динамической области оперативной памяти (процедура OvrSetBuf). В общем случае невозможно выбрать идеальный размер буфера, так чтобы, с одной стороны, он имел минимальный размер, а с другой – обеспечивал незначительный «свопинг». Этот размер обычно выбирают в результате эксперимента с разработанной программой, достигая определенного компромисса между требуемым быстродействием и доступным объемом ОП.    Cвопинг - процесс пересылки или «перекачки» оверлеев по мере их использования из ovr-файла в буфер       Общая схема программы, использующей оверлеи: {$ F+} Program PrOvr; {Основная программа} Uses     Overlay, Ovr1, …, OvrN; {Полный список используемых модулей, в том числе и оверлейных}     {$0 Ovr1} {Директива компилятора, которая указывает, что модуль Ovr1 будет оверлейным}     {$0 Ovr2}     …     {$0 OvrN} Begin {Начало раздела операторов основной программы}     OvrInit ('PrOvr.Ovr'); {Инициализация подсистемы управления оверлеями} {Если при этом возникла ошибка}     If (OvrResult OvrOk)then         begin             Case OvrResult of                 OvrError: Writeln ('Программа не имеет оверлеев');                 OvrNotFound: Writeln ('Файл оверлеев не найден')     Else         Writeln ('Ошибка монитора управления оверлеями');         End;     Halt (1) End; OvrSetBuf (OvrGetBuf+MemAvail); {Увеличение размера оверлейного буфера до максимально возможного значения} … {Далее по смыслу программы} … End. {Оверлейные модули транслируются отдельно} {Первый оверлейный модуль} {$ 0+, F+} Unit     Ovr1; Interfase … Implementation … … {{Последний оверлейный модуль} {$ 0+, F+} Unit     OvrN; Interfase … Implementation …       Эта программа содержит оверлейные модели Ovr1, …, OvrN. При инициализации подсистемы управления оверлеями могут возникнуть ошибки. Поскольку эти ошибки не позволяют программе дальше нормально функционировать, то выдается соответствующее сообщение об ошибке и программа заканчивается. Если инициализация подсистемы управления оверлеями прошла успешно, то далее процедура OvrSetBuf устанавливает максимальный размер оверлейного буфера. Ошибки на данном этапе игнорируются, т.к. любая из них позволяет использовать минимальный размер буфера. Во многих случаях к увеличению размера оверлейного буфера следует подходить осторожно,поскольку динамическая область памяти часто используется и для других целей (размещение динамических переменных, драйверов внешних устройств и т.д.).       Пример 1: {$ F+} Program A1; Uses     HO, Overlay, H1, H2; {$0 H1} {$0 H2} Var     f: real; Begin     HHH;     KKK;     F:= 2;     Writeln ('f= ', f);     F:= f+h+k;     Writeln ('f+h+k= ', f); End.       Эта программа использует два оверлейных модуля H1 и H2, которые кроме разделов интерфейса и реализации имеют также раздел инициализации. Т.к. разделы инициализации этих модулей вызываются раньше, чем загрузка самой программы, то требуется еще один неоверлейный модуль НО – для вызова процедуры OvrInit. При этом модуль НО должен быть первым в операторе uses. Unit HO; Interfase     Uses         Overlay; Implementation Begin     OvrInit ('A1.ovr') End. {$0+, F+}     Unit H1 Interfase Var     h: real;     Fi: text; Procedure HHH; Implementation Procedure HHH;     Begin         H:= 5;         Writeln ('h= ', h);     End;     Begin         Assign (fi, 'f: \f');         Rewrite (fi);     End. {$0+, F+}     Unit H2 Interfase Var     k: real; Procedure KKK; Implementation Procedure KKK;     Begin         {k:= 5;}         Writeln ('k= ', k);     End; Begin     K:=5; End.       В результате выполнения программы А1 на печать буден выведен следующий текст:       H = 5.0000000000E+00       K = 5.0000000000E+00       F = 2.00000000000E+00       f+h+k = 1.2000000000E+01

Соседние файлы в папке Module2