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

Методы / Куликова Н.В., Петровская Е.Н. (ч.1,2)

.pdf
Скачиваний:
58
Добавлен:
11.06.2015
Размер:
2.62 Mб
Скачать

-K

Сохраняет (не стирает) временные файлы, созданные

 

утилитой MAKE. Все временные файлы имеют формат

 

MAKEnnnn.$$$, где nnnn лежит в диапазоне от 0000 до

 

9999

-N

Выполняет MAKE как Microsoft NMAKE

-Uидентиф

Отменяет все заданные ранее описания названного

 

идентификатора

-W

Заносит в файл MAKE.EXE заданные в настоящий мо-

 

мент нестроковые параметры (типа -s или -a)

-a

Проверяет зависимости включаемых файлов и вложен-

 

ных включаемых файлов, связанных с файлами .OBJ, и

 

обновляет файл .OBJ, если файл .H изменен

-c

Кэширует информацию о зависимостях, что улучшает

 

производительность MAKE. Не используйте его с –a, а

 

также если MAKE изменяет включаемые файлы

-dкаталог

Используется с -S для задания диска и каталога, кото-

 

рый MAKE использует для свопинга (для MAKER не

 

действует)

-e

Игнорирует макрокоманду, если ее имя совпадает с

 

именем переменной операционной среды

-i

Игнорирует состояние завершения всех запускаемых

 

из MAKE программ и продолжает процесс построения

-m

Выводит дату и время каждого файла при обработке

 

его MAKE

-n

Выводит команды, но не выполняет их (полезно ис-

 

пользовать при отладке)

-p

Перед выполнением формирующего файла выводит

 

все макроопределения и неявные правила

-q

Возвращает 0, если цель имеет новую дату и время и не

 

0 в противном случае (используется в командных фай-

 

лах)

-r

Игнорирует все правила, определенные в BUIL-

 

TINS.MAK

-s

Подавляет вывод команд на экран

-S

Выгружает MAKE из памяти при выполнении команд,

 

что уменьшает использование памяти и позволяет

 

компилировать большие модули. Для MAKER не дей-

 

ствует

81

5. Оверлеи (VROOMM)

Оверлеями называются части кода программы, совместно использующие общую область памяти. Одновременно в памяти находятся только те части программы, которые в текущий момент нужны данной функции.

Оверлеи могут существенно снизить во время выполнения программы требования к выделяемой памяти. При помощи оверлеев можно создавать программы, значительно превышающие по размеру общую доступную память системы, поскольку одновременно в памяти находится лишь часть данной программы.

Оверлеи используются только в 16-разрядных программах DOS. В приложениях WINDOWS для сокращения объема используемой памятиможнопометитьсегментыкакDiscardable (выгружаемые).

Работа программ с оверлеями

Программа управления оверлеями (VROOMM Virtual Runtime Object-Oriented Memory Manager) выполняет автоматически большую часть работы по организации оверлеев.

В обычных оверлейных системах модули группируются в базовый модуль и набор оверлейных модулей. Подпрограммы в данном оверлейном модуле могут вызывать подпрограммы из этого же модуля и из базового модуля, но не из других модулей. Оверлейные модули перекрывают друг друга, т.е. одновременно в памяти может находиться только один оверлейный модуль, и все они при активизации занимают один и тот же участок физической памяти. Общий объем памяти, необходимой для запуска данной программы, определяется размером базового и максимального оверлейного модуля. Эта обычная схема не обеспечивает достаточной гибкости. Она требует полного учета всех возможных обращений между модулями программы и соответственно планируемой группировки оверлеев. Если невозможно разбить программу в соответствии с взаимозависимостью обращений между ее модулями, то нельзя разбить ее на оверлеи.

Схема VROOMM совершенно иная. Она обеспечивает динамический свопинг сегментов. Основной единицей свопинга является сегмент. Сегмент может состоять из одного или нескольких модулей. Любой сегмент может вызывать другой сегмент. Вся память делится на базовую область и область свопинга. Как

82

только встречается вызов функции, которая не находится ни в базовой, ни в области свопинга, сегмент, содержащий вызываемую функцию, помещается в область свопинга, возможно, выгружая оттуда другие сегменты. Это мощное средство, подобное виртуальной программной памяти. В данном случае не требуется разбивать код на статические отдельные оверлейные блоки. Необходимо просто запустить программу!

Когда возникает необходимость поместить сегмент в область свопинга, и эта область имеет достаточно свободного места, данная задача выполняется просто. Если же нет, то из области свопинга, чтобы искомая область освободилась, должен быть выгружен один или более сегментов. Чтобы выбрать сегменты для выгрузки, действует достаточно сложный алгоритм. Упрощенная версия такова: если в области свопинга имеется неактивный сегмент, то для выгрузки выбирается он. Неактивными считаются сегменты, в которых в текущий момент нет выполняемых функций; в противном случае, берется активный сегмент. Удаление сегментов из памяти продолжается до тех пор, пока в области свопинга не образуется достаточно свободной памяти для размещения там требуемого сегмента. Такой метод называется динамическим свопингом.

Чем больше памяти выделено для области свопинга, тем лучше работает программа. Область свопинга работает как кэшпамять: чем больше кэш, тем быстрее работает программа. Наилучшие значения размера области свопинга определяются размерами рабочего множества данной программы.

После загрузки оверлея в память он помещается в оверлейный буфер, который расположен в памяти между сегментом стека и дальней, динамически распределяемой, областью. По умолчанию размер оверлейного буфера вычисляется и устанавливается при загрузке программы, но его можно изменить при помощи глобальной переменной _ovrbuffer. Если достаточный размер памяти недоступен, то появляется сообщение об ошибке

DOS: Program too big to fit in memory.

Важной возможностью программы управления оверлеями является ее способность при удалении моделей из оверлейного буфера выполнять их свопинг с дополнительной расширенной памятью. Следующий раз, как только данный модуль понадобится,

83

он в этом случае будет не считываться с диска, а просто копироваться из этой памяти. Это существенно ускоряет свопинг.

Оптимальное использования оверлеев Borland C++

Для полного использования преимуществ оверлейных структур, создаваемых Borland C++, необходимо

минимизировать резидентный код (резидентные библиотеки исполняющей системы, обработчики прерываний и драйверы устройств);

установить размер оверлейного пула таким образом, чтобы добиться наиболее комфортных условий для создаваемой программы (начать со 128 К и регулировать этот размер вверх и вниз, пока не установится желаемое соотношение между быстродействием и размером программы);

подумать об универсальности и многосторонности создаваемого кода: воспользоваться преимуществами оверлейной структуры и обеспечить поддержку обработки специальных случаев, интерактивную справочную систему по программе и прочие средства, являющиеся достоинствами с точки зрения конечного пользователя.

Требования при создании оверлеев

1.Минимальная часть программы, которая может выделяться в качестве оверлея, это сегмент.

2.Прикладные программы с оверлейной структурой должны иметь одну из моделей памяти medium , large или huge; модели tiny, small и compact оверлеи не поддерживают.

3.Перекрывающиеся сегменты подчиняются обычным правилам слияния сегментов, т.е. в одном и том же сегменте может участвовать несколько объектных файлов.

Генерация оверлеев во время компоновки полностью не зависит от управления сегментами во время исполнения программы; компоновщик не включает автоматически каких-либо кодов для управления оверлеями. Действительно, с точки зрения компоновщика программа управления оверлеями является просто одним из подлежащих компоновке участков кода. Единственное предположение, которое делает компоновщик, состоит в том, что программа управления оверлеями воспринимает вектор прерываний (обычно INT

84

3FH), через который происходит управление динамической загрузкой. Такой уровень «прозрачности» упрощает создание пользовательских программ управления оверлеями, наилучшим образом отвечающихтребованиямконкретнойприкладнойпрограммы.

Оверлеи и обработка исключительных ситуаций

Если пишется оверлейная программа, содержащая конструкции для обработки исключительных ситуаций, то существует ряд ситуаций, которых следует избегать. Следующие программные элементы не могут содержать конструкцию обработки исключительных ситуаций:

не расширяемые подставляемые функции;

шаблоны функций;

функции-элементы или шаблоны классов.

Конструкция обработки исключительной ситуации включает в себя написанный пользователем блок try/catch и __try/__except. Кроме того, компилятор также может включать в себя обработчики исключительных ситуаций и блоки с локальными динамическими переменными, спецификациями исключительных ситуаций и некоторые выражения new/delete.

Если попытаться использовать в оверлее вышеуказанные конструкции обработки исключительных ситуаций, компоновщик идентифицирует функцию и модуль сообщением

Error: Illegal local public in функция in module модуль

Когда эта ошибка вызывается подставляемой функцией, можно переписать функцию таким образом, чтобы она не была подставляемой. Если это вызвано шаблоном функции, можно

удалить из функции все конструкции обработки исключительной ситуации;

удалить функцию их оверлейного модуля.

Особенно внимательно нужно строить оверлейную программу, которая использует множественное наследование. Попытка создать оверлейный модуль, который определяет или использует конструкторы или деструкторы классов с множественным наследованием, может привести к тому, что компоновщик будет генерировать следующее сообщение об ошибке:

Error: Illegal local public in класс: in module модуль

85

Когда генерируется такое сообщение, идентифицированный компоновщиком модуль не следует делать оверлейным.

В классе контейнера (в BIDS?.LIB) есть механизм обработки исключительной ситуации, который по умолчанию выключен. Однако диагностическая версия генерирует исключительные ситуации и не может использоваться в оверлеях. По умолчанию класс string может генерировать исключительные ситуации, и его не следует использовать в программах с оверлеями.

Использование оверлеев

Для создания программы с оверлейной структурой все ее модули должны компилироваться с включенным параметром компилятора -Y. Для того, чтобы сделать оверлейным конкретный модуль, его следует компилировать с параметром -Yo (-Yo автоматически включает параметр -Y).

Параметр -Yo распространяется на все модули и библиотеки, следующие за ней в командной строке компилятора BCC. Отменить ее можно, задав -Yo-. Эти два параметра являются единственными параметрами командной строки, которые могут следовать после имен файлов. Например, для того, чтобы сделать оверлейным модуль OVL.C, но не библиотеку GRAPHICS.LIB, можно использовать любую из следующих командных строк:

BCC -ml -Yo ovl.c -Yo- graphics.lib

или

BCC -ml graphics.lib -Yo ovl.c

Если при запуске компоновщика TLINK явно задана компоновка файла .EXE, то в командной строке компоновщика должен задаваться параметр /o.

Предположим, необходимо иметь оверлейную структуру в программе, состоящей из трех модулей: MAIN.C, O1.C и O2.C. Оверлеями должны являться модули O1.C и O2.C. Программа MAIN.C содержит зависящие от текущего времени подпрограммы и обработчики прерываний и потому должна оставаться резидентной. Предположим, что данная программа использует модель памяти large.

Следующая команда позволяет выполнить данную задачу:

BCC -ml -Y main.c -Yo o1.c o2.c

В результате получится выполняемый файл MAIN.EXE с двумя оверлеями.

86

Разработка программ с оверлеями

При компиляции оверлейного модуля необходимо использовать большую модель памяти (medium, large или huge). При всяком вызове функции из оверлейного модуля необходимо гарантировать, что все активные в текущий момент функцииявляются дальними.

Необходимо компилировать все оверлейные модули с парамет- ром-Y, чтообеспечитоверлейнуюструктуругенерируемого кода.

Невыполнение требования дальних вызовов в оверлейной программе приведет при выполнении программы к непредсказуемым и, возможно, катастрофическим результатам.

Размер оверлейного буфера по умолчанию в два раза превышает размер самого большого оверлея. Для большинства прикладных программ такое умолчание вполне адекватно. Однако, когда какаялибо функция программы реализована несколькими модулями, каждый из которых является оверлейным, и общий размер этих модулей превышает размер оверлейного буфера, частый вызов модулей друг другом приведет кинтенсивному свопингу.

Очевидно, что решение здесь заключается в увеличении размера оверлейного буфера до таких размеров, чтобы в любой момент времени в нем помещались все часто вызывающие друг друга оверлеи. Это можно сделать, установив через глобальную переменную _ovrbuffer требуемый размер в параграфах. Например, для установки размера оверлейного буфера равным 128 К, включается в код следующий оператор:

unsigned _ovrbuffer = 0x2000.

Общей формулы для определения идеального размера оверлейного буфера не существует.

Нельзя создавать оверлейные модули, содержащие обработчики прерываний, а также в случаях небольших или критичных к быстродействию программ. Вследствие нереентерабельной природы операционной системы DOS модули, которые могут вызываться функциями прерываний, не должны быть оверлейными.

Программа управления оверлеями Borland C++ полностью поддерживает передачу оверлейных функций как аргументов, присвоение и инициализацию переменных типа указателя функции, адресующих оверлейные функции, а также вызов оверлейных подпрограмм через указатели функций.

87

Отладка оверлейных программ

Большинство отладчиков либо имеет весьма ограниченные средства отладки программ с оверлейной структурой, либо вообще не имеет таких средств. Иначе дело обстоит с интегрированным со средой разработки программ отладчиком Borland C++ и автономным отладчиком фирмы Borland (Turbo Debugger). Оба эти отладчика полностью поддерживают пошаговую отладку и установку точек останова в оверлеях совершенно «прозрачным» способом. Благодаря использованию оверлеев есть возможность легко разрабатывать и отлаживать громоздкие прикладные программы как в интегрированнойсреде, такиприпомощиTurbo Debugger.

Свопинг

Если в системе компьютера установлена дополнительная или расширенная память, можно сообщить программе управления оверлеев, что она должна использовать эту память при свопинге. В этом случае при удалении модуля из оверлейного буфера (когда туда требуется загрузить новый модуль, а буфер полон) программа управления оверлеями может поместить удаляемый модуль в эту память. При любой последующей загрузке этого модуля за счет того, что модуль перемещается в памяти, а не считывается с диска, экономится время.

В обоих случаях есть две возможности: программа управления оверлеями может либо обнаруживать наличие дополнительной или расширенной памяти самостоятельно и затем брать на себя управление этой памятью, либо использовать уже обнаруженную и распределенную часть такой памяти. В случае расширенной памяти обнаружение памяти не во всех случаях выполняется удачно, поскольку многие программы кэширования памяти и программы организации виртуального диска могут использовать эту память, не делая об этом никаких отметок. Чтобы избежать этих проблем, необходимо сообщить программе управления оверлеями начальный адрес расширенной памяти и какой участок ее можно безопасно использовать. Borland С++ предусматривает две функции, которые позволяют инициализировать расширенную и дополнительную память _OvrInitEms и _OvrInitExt.

88

6. Компоновщик TLINK

TLINK и TLINK32 это инструментальные средства, работающие в режиме командной строки, которые, комбинируя другие модули (файлы .OBJ) и библиотечные модули (.LIB), создают выполняемые файлы. В IDE имеются встроенные версии этих компоновщиков. Поскольку компилятор автоматически вызывает компоновщик, явный вызов его не требуется, пока вы не отмените этап компоновки (параметр -c).

TLINK использует файл конфигурации с именем TLINK.CFG, файл подсказки и параметры командной строки, задающие компоновку объектных модулей, библиотек и ресурсов в файл .EXE или .DLL. Компоновщик интегрированной среды использует параметры, заданные в диалоговом окне Project Options. Командная строка TLINK имеет следующий синтаксис:

TLINK [@файл_подсказки][параметры] файл_запуска объектн_файлы, имя_exe, [файл_map], [библиотеки] библ_исп_системы [библ_импорта], [файл_определений], [файлы_res]

параметры это параметры TLINK, управляющие его работой (перед ними указывается символ «-» или «/»);

файл_запуска это модуль инициализации Borland для выполняемых или DLL-файлов, определяющий порядок загрузки сегментов программы; он должен следовать в списке объектных файлов первым;

объектн_файлы это компонуемые объектные файлы .OBJ с указанием маршрута;

имя_exe это имя, назначаемое создаваемому выполняемому файлу (.EXE или .DLL);

необязательное имя файл_map задает имя файла карты распределения памяти; если имя не задается, то оно будет соответствовать имени исходного файла с добавлением расширения .MAP; библиотеки это указываемые при компоновке библиотечные файлы; если эти файлы не находятся в текущем каталоге или по маршруту поиска, то нужно указать маршрут; библ_исп_системы задает библиотеку исполняющей системы Borland; если библиотека не указывается, то она не компонуется;

89

библ_импорта это библиотека импорта WINDOWS, обеспечивающая доступ к функциями API Microsoft WINDOWS; файл_определений это файл определения модуля (.DEF) для выполняемого файла WINDOWS; если он не задается, то приложение создается на основе заданных по умолчанию установок; файлы_res задают список файлов ресурсов .RES, используемых для формирования выполняемого файла.

Если у имен файлов отсутствуют расширения, то TLINK добавляет следующие расширения:

* .OBJ

Для объектных файлов;

* .EXE

Для выполняемых файлов (когда используется параметр

 

/t или /Td, выполняемый файл получает расширение

 

.COM, а не .EXE);

* .DLL

Для библиотек динамической компоновки (когда исполь-

 

зуется параметр /Twd или параметр /Tw и файл определе-

 

ниямодуля, задающийбиблиотеку);

* .MAP

Для файлов карты распределения памяти;

* .LIB

Для файлов библиотек;

* .DEF

Для файлов определения модуля.

* .RES

Для файлов ресурсов.

 

Опции компоновщика (редактора связей) TLINK

 

 

/x

Не создавать файл карты (map)

/m

Создать файл карты

/s

То же, что /m, но дополнительно в файл карты включается

информация о сегментах (адрес, длина в байтах, класс, имя

 

сегмента и т.д.)

/l

Создать раздел в файле карты с номерами строк

/n

Игнорироватьбиблиотеки, указываемыедругимикомпиляторами

/c

Различать строчные и прописные буквы в идентификаторах (в

том числе и внешних)

/v

Включить отладочную информацию в выполняемый файл

/3

Поддержка 32-битного кода

/d

Предупреждать о дублировании символов в компонуемых

 

библиотеках

/t

Создать файл типа .com (по умолчанию .exe)

90