На Фиг. 5.16 приведена полученная в результате редактирования карта
связей. Так как рассматриваемый пример прост, то и карта не очень
содержательна. Каждому сегменту в исполняемом файле соответствует
отдельная строка карты. В строке последовательно указаны значения
начального и конечного адресов каждого сегмента в том виде, в каком
они будут загружены в память. Заметьте, что размер сегмента CODE
равен 3CH. Это является суммарным размером сегментов CODE в двух
программных модулях. Другой сегмент в нашем примере - это сегмент
STACK размером 80H байт.
По поводу адресов, приведенных в карте связи, нужно сделать
следующие замечания. Во-первых, все они являются 20- битовыми
адресами и отсчитываются от ячейки 0. Так как загрузка программы
будет осуществляться DOS, то занрузчик изменит значения этих
адресов. Однако относительно друг друга их значения останутся
такими же. В отношении сегментов следует еще отметить, что в памяти
они не располагаются последовательно. Хотя длина сегмента CODE
равняется только 3CH, сегмент STACK начинается с адреса 40H.
Сегменты должны располагаться на границах параграфов для того,
чтобы адреса смещения сохраняли правильные значения. Благодаря
привязке к границам параграфов, сегментные регистры указывают точно
на первую ячейку сегмента. Следовательно, в нашем случае редактор
связей расположил сегмент STACK на первой границе параграфа сразу
же после конечного адреса сегмента CODE. С учетом того, что конец
сегмента CODE равен 3BH, следующий адрес ячейки, который делится на
16, будет равен 40H.
----------------------------------------------------
Start Stop Length Name Class
00000H 0007FH 00080H STACK
00080H 000CEH 0004FH CODE
Program entry point at 0008:0000
----------------------------------------------------
Фиг. 5_16 Карта связей для Фиг. 5.13 и 5.14
Возможно вы заметили, что общая длина сегментов CODE в
действительности не равна 3CH. В отсутствие других спецификаций
редактор связей поместил начало каждой части сегмента CODE на
границах параграфов. Длина первого модуля FIG5=13 равняется 2BH.
Следующий модуль, FIG5=14, редактор связей поместил на следующей
границе параграфа, в данном случае по адресу 30H. Так как длина
второго модуля равна 0CH, общий размер сегмента CODE будет равен
03CH. Выравнивание по границам параграфов выполняется по умолчанию
совместно с ассемблированием и редактированием связей. Оператор
языка ассемблера SEGMENT может, если нужно, изменить это
выравнивание на побайтовое (BYTE), либо пословно (WORD). При
выравнивании типа BYTE программные программные упаковываются в один
сегмент. В смысле экономии памяти это наиболее эффективный способ
объединения модулей. Однако выравнивание по границе параграфа
гарантирует, что во время выполнения программы не возникает никаких
трудностей с адресацией сегментов. Если в программе производятся
вычисления адресов и выравнивание производилось не по границам
параграфов, то возможно возникновение ошибок.
В конце карты связей указывается входная точка исполняемого
файла. Этот адрес, как и другие, вычисляется по отношению к началу
исполняемого модуля и перераспределяется загрузчиком. Имеется
несколько способов указания стартового адреса для программы типа
.EXE. При одном из способов программа выполняется, начиная с
первого байта программного модуля. При этом вы должны следить за
тем, чтобы в первом байте первого сегмента рабочего файла
содержалась команда, с которой вы хотите начать выполнение. Более
предпочтительным является способ задания входной точки в операторе
END головной программы. На Фиг. 5.13 последним в программе является
оператор
END START
где START - это метка первой выполняемой команды. Так как
модули связаны друг с другом в определенном порядке, то эта же
команда будет первой и в программе. Однако если модули связать в
обратном порядке, то входная точка будет располодена правильным
образом. В этом можно убедиться на практике.
При любой операции связывания должен быть только один оператор
END с указанием стартового адреса. Обратите внимание, что в
подпрограмме FIG5=14 в операторе END входная точка не указана. Если
имеется более одной входной точки, то редактор связей обычно
выбирает ту, которая указана последней. Лучше непосредственно
задавать входную точку, чем допускать вероятность того, что
редактор связей выберет не ту входную точку. Имейте в виду, что
этот способ задания входной точки программы пригоден только в
случае файла типа .EXE. Программа типа .COM всегда выполняется,
начиная со смещения 100H сегмента команд.