- •5.Модульное программирование
- •5.1. Методы и проблемы модульного программирования
- •5.1.1. Реализация модульности за счет библиотек макроопределений
- •5.1.2. Реализация модульности за счет связывания объектных модулей
- •Объединение логических сегментов
- •Описание межмодульных обращений
- •5.2. Библиотеки объектных модулей
- •5.2.1. Создание библиотек объектных модулей и операции над ними
- •Команды библиотекаря
- •5.2.2. Использование библиотек объектных модулей
Описание межмодульных обращений
Для описания межмодульных обращений используются директивы глобального объявления PUBLICиEXTRN.
Директива PUBLICслужит для описания переменных или меток, определенных в данном файловом модуле, но к которым возможно обращение из других модулей. Ее формат имеет вид:
PUBLICИмя{, Имя . . .}
Тип переменных или меток в директиве PUBLICне указывается, так как они определены в этом же модуле и известны ассемблеру.
Директива EXTRNописывает внешние по отношению к данному файловому модулю переменные и метки, к которым имеются обращения из него. Ее формат имеет вид:
EXTRN Имя:Тип{, Имя:Тип . . .}
В качестве типа для переменных может указываться BYTE,WORDилиDWORD, а для метокNEARилиFAR.
Директивы PUBLICиEXTRNрекомендуется размещать в начале файловых модулей для исключения проблем, связанных с обращением вперед.
Пример 5.7:
Написать программу, состоящую из двух файловых модулей, в каждом из которых должно обеспечиваться вычислениеS=A+BиS=AB,гдеA, Bнекоторые слова в памяти.
Текст программы для решения этой задачи с учетом всех проблем модульного программирования будет иметь вид:
; файловый модуль MOD1.asm (главный)
PUBLICA1,B1,S1,AddW,SubW ;Описание внутренних ;операндов
EXTRNA2:WORD,B2:WORD;S2:WORD ;Описание ;внешних операндов
Data SEGMENT WORD PUBLIC
A1 DW?
B1 DW ?
S1 DW?
Data ENDS
Code SEGMENT BYTE PUBLIC
ASSUME CS:Code, DS:Data
AddW PROC NEAR;Описание подпрограм- ADD AX, DX ;мы сложения
RET
AddW ENDP
SubW PROC NEAR ;Описание подпрограм- SUB AX, DX ;мы вычитания
RET
SubW ENDP
Start:. . . . . . . . . .
MOV AX, A2 ;Вычисление
MOV DX, B2 ;S2=A2+B2
CALL AddW
MOV S2, AX
. . . . . . . . . .
MOV AX, A1 ;Вычисление
MOV DX, B1 ;S1=A11
CALL SubW
MOV S1, AX
Code ENDS
ENDStart ;Конец главного модуля
; файловый модуль MOD2.asm (подчиненный)
PUBLICA2,B2,S2 ;Описание внутренних ;операндов
EXTRNA1:WORD,B1:WORD,S1:WORD ;Описание
EXTRNAddW:NEAR,SubW:NEAR ;внешних операндов
Data SEGMENT WORD PUBLIC
A2 DW?
B2 DW?
S2 DW?
Data ENDS
Code SEGMENT BYTE PUBLIC
ASSUMECS:Code,DS:Data
. . . . . . . . . .
MOV AX, A1 ;Вычисление
MOV DX, B1 ;S1=A1+B1
CALL AddW
MOV S1, AX
. . . . . . . . . .
MOV AX, A2 ;Вычисление
MOV DX, B2 ;S2=A22
CALL SubW
MOV S2, AX
Code ENDS
END ;Конец подчиненного модуля
При раздельной трансляции этих модулей ассемблер не может полностью сформировать их машинный код, так как неизвестны адреса внешних обращений. Однако, зная тип внешних обращений, он зарезервирует необходимое количество байтов для описания этих операндов и внесет соответствующие пометки в объектные файлы. При связывании файловых модулей редактор связей просматривает эти пометки и, используя доступную ему информацию, определяет все необходимые адреса, подставляя их в зарезервированные области. Таким образом создается общий исполняемый файл программы, в котором все адреса полностью определены.
Необходимо обратить внимание на то, что подчиненный модуль не имеет стартовой метки программы. Поэтому при его подключении к главному модулю в общий файл программы включаются все имеющиеся в нем команды, в том числе и команды описания подпрограмм. В результате в общем программном файле команды, составляющие тело подпрограммы, могут оказаться между исполняемыми фрагментами главного и подчиненного модулей, что недопустимо. Отсюда следует, что в подчиненные модули целесообразно включать либо только описания подпрограмм, либо только исполняемые фрагменты программы.