Принципы разработки модулей

Разработка многомодульных программ

Разработка многомодульных программ ведется в соответствии с принципом физической декомпозиции, когда формируется набор взаимосвязанных модулей, каждый из которых выполняет определенную задачу общего процесса. Каждый модуль независимо от остальных транслируется в объектный модуль. Затем все объектные модули объединяются в единую машинную программу с помощью компоновщика TLINK (рис. 29)

 

 
 

 


Рис. 29. Трансляция и компоновка многомодульной программы.

 

 

Например, если программа состоит из двух объектных модулей M1.OBJ и M2.OBJ, то команда компоновки будет следующей:

 

TLINK M1+M2, M

 

В первом параметре через символ «+» перечисляются имена всех объектных модулей (если расширение OBJ, его можно не указывать), а второй параметр указывает имя исполняемого файла.

Каждый модуль многомодульной программы представляет последовательность предложений, с последней директивой END:

 

< предложение >

...

< предложение >

END [< точка входа >]

 

Среди модулей должен быть выделен основной (главный), с которого начинается выполнение программы и который передает управление остальным модулям. Главный модуль отличается наличием точки входа. Если точка входа определена и в других модулей, главным модулем будет считаться тот, что был указан первым в параметрах компоновщика.

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

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

 

PUBLIC < имя >,..., < имя >

 

Директива может быть указана в любом месте модуля любое число раз. Однако обычно для удобства ее помещают в самом начале модуля.

С другой стороны, модуль, импортирующий идентификаторы, метки и подпрограммы, должен продекларировать их с помощью директивы:

 

EXTRN < имя > : < тип >,..., < имя > : < тип >

 

где < тип > – тип данных BYTE, WORD, DWORD, ABS, NEAR или FAR.

 

Директива также может быть указана в любом месте модуля любое число раз. Типы BYTE, WORD и DWORD используются для имен переменных, тип ABS – для имен констант, NEAR и FAR – для меток или имен процедур.

Рассмотрим применение директив PUBLICи EXTRN. Следующий модуль экспортирует процедуру PRC и переменную IDW:

 

PUBLIC PRC, ID

 

DATASG SEGMENT

IDW DW 200h

DATASG ENDS

 

CODESG SEGMENT

ASSUME CS: CODESG, DS: DATASG

PRC PROC FAR

...

PRC ENDP

CODESG ENDS

 

END

 

Второй модуль является главным. Он импортирует объявления первого модуля. Для доступа к переменной IDW необходимо настроиться на программный сегмент DATASG. Однако напрямую обратиться к DATASG невозможно, т.к. имена сегментов запрещено описывать в разделе PUBLIC. Поэтому здесь используется следующий прием.

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

 

EXTRN PRC: FAR, IDW: WORD

 

CODE SEGMENT

ASSUME CS: CODE

S: MOV AX, SEG IDW

MOV ES, AX

...

MOV BX, ES:IDW

...

CODE ENDS

 

END S