
- •5.Модульное программирование
- •5.1. Методы и проблемы модульного программирования
- •5.1.1. Реализация модульности за счет библиотек макроопределений
- •5.1.2. Реализация модульности за счет связывания объектных модулей
- •Объединение логических сегментов
- •Описание межмодульных обращений
- •5.2. Библиотеки объектных модулей
- •5.2.1. Создание библиотек объектных модулей и операции над ними
- •Команды библиотекаря
- •5.2.2. Использование библиотек объектных модулей
5.Модульное программирование
При разработке сложных программ общая задача должна разбиваться на подзадачи, реализуемыми независимыми программными модулями. В качестве модулей, как правило, используются подпрограммы, вызываемые с макроуровня программы.
На этапе подготовки программы весь ее текст может быть помещен в один файл. В этом случае исходный файл сложной программы становится очень большим, что существенно усложняет его редактирование и трансляцию.
Для исключения этого недостатка необходимо каким-либо образом представить общую программу в виде совокупности отдельных файловых модулей небольшого размера с последующим их объединением в общий исполняемый файл программы. Эта идея лежит в основе модульного программирования.
5.1. Методы и проблемы модульного программирования
Модульное программирование может быть реализовано различными путя-ми. Простейшим из них является использование библиотек макроопределений.
5.1.1. Реализация модульности за счет библиотек макроопределений
В этом случае некоторые фрагменты исходного текста программы оформляются в виде макроопределений и выносятся в отдельные файлы библиотек. В результате исходный файл программы представляется в виде совокупности нескольких файлов меньшего размера, что упрощает их редактирование.
Библиотеки макроопределений включаются в исходный текст программы с помощью директивы INCLUDE(см. подраздел 3.15.4).
Подобным образом можно выделить в отдельный файл с последующим его подключением к исходному файлу не только макроопределения, но и любой другой фрагмент программы.
Недостатком такого подхода является то, что выделенные файлы подключаются к исходному файлу и транслируются вместе с ним при каждой его трансляции. В результате общее время трансляции программы в этом случае не уменьшается и для сложных программ может иметь недопустимые значения.
5.1.2. Реализация модульности за счет связывания объектных модулей
Дальнейшим развитием модульного программирования является представление всей программы в виде совокупности независимых файловых модулей с возможностью их раздельной трансляции. Объединение раздельно транслированных модулей в общий исполняемый файл программы возможно с помощью редактора связей на этапе компоновки программы.
Однако, при таком подходе возникают специфические проблемы объединения модулей. Они обусловлены следующими причинами:
1) все файловые модули могут иметь идентичную структуру, включая в себя логические сегменты данных, стека и программного кода, которые при их объединении должны образовать общие логические сегменты программы;
2) в любой программе между модулями существуют связи по данным и управлению и, следовательно, из одного модуля возможны обращения к поименованным операндам (переменным и меткам) из других модулей, а другие модули могут обращаться к аналогичным элементам в данном модуле.
При раздельной трансляции исходных файловых модулей ассемблер будет обнаруживать неопределенные имена, что вызовет, без принятия дополнитель-ных мер, фиксацию множества ошибок.
Для решения этих проблем в ассемблер были введены директивы описания типа объединения логических сегментов связываемых файловых модулей, а также описания межмодульных обращений. При трансляции отдельных файловых модулей эта информация включается в их объектные файлы и используется редактором связей для определения всех адресов, которые были неизвестны ассемблеру.
Таким образом, подготовка многомодульной программы к исполнению включает в себя следующие этапы:
1) создание исходных файлов независимых программных модулей;
2) раздельная трансляция всех исходных файловых модулей;
3) объединение полученных объектных файлов отдельных модулей в общий исполняемый файл программы.
Исходные файлы модулей создаются обычным образом (см. подраздел 4.1). Исходный текст всех объединяемых модулей должен завершаться директивой END. Но только в одном из них в директивеENDможет указываться стартовый адрес программы. Этот модуль считается главным и должен содержать макроуровень программы, а остальные модули являются подчиненными и должны присоединяться к главному модулю.
Трансляция модулей также осуществляется обычным образом (см. подраздел 4.2). Однако, объединяемые объектные модули могут быть получены не только ассемблированием с помощью MASM, но и компиляторами языков высокого уровня, например, Си или Паскаль. Это позволяет писать математически сложные программные модули на языках высокого уровня, а модули логического управления на ассемблере, что упрощает процесс разработки программ.
Объединение объектных модулей в общий исполняемый файл также осуществляется обычным образом с помощью редактора связей LINK (см. подраздел 4.3).
Пример 5.1:
Создать исполняемый файл программы, состоящей из трех исходных файловых модулейX.asm, Y.asmиZ.asm, которые могут транслироваться раздельно.
Процесс подготовки такой программы будет иметь вид:
MASM X ;ассемблирование X.asm с формированием X.obj.
MASM Y ; ассемблирование Y.asm с формированием Y.obj.
MASM Z ; ассемблирование Z.asm с формированием Z.obj.
LINK X+Y+Z,PROGобъединение файлов X.obj, Y.obj и Z.obj с формированием исполняемого файла программы PROG.exe.
Для реализации модульного программирования необходимо рассмотреть директивы для объединения логических сегментов, а также для описания межмодульных обращений в связываемых файловых модулях.