Многомодульность



Многомодульность


    Как указывает само имя программы LINK, ее основное назначение
    "связать", или объединить, несколько объектных модулей в один
    выполняемый модуль.  Все рассмотренные до сих пор примеры
    относились к одномодульным программам, т.е.  все, что они должны
    были выполнять, реализовывалось в одном исходном модуле.  Однако
    этот путь не всегда возможен или желателен.
 
      Имеется ряд причин, в силу которых программа программа сожет
    быть разбита на несколько модулей. Во-первых, размер программы.
    Редактирование очень большой программы становится весьма громоздким
    и трудным делом, а ее ассемблирование занимает много времени.
    Предположим, что вы допустили ошибку в единственной строке
    ассемблерной программы, состоящей из 5000 строк. Чтобы изменить
    одну эту строку, необходимо выполнить редактирование всей
    программы. После этого нужно оттранслировать всю программу из 5000


    строк, что занимает довольно много времени. После относительно
    быстрого этапа редактирования связей программа готова к выполнению.
 
      Предположим, теперь, что вместо того, чтобы иметь дело с
    программой, состоящей из 5000 строк, вы разбиваете ее на десять
    программых модулей, по 500 строк в каждом. Для внесения изменений в
    единственную строку вам необходимо выполнить редактирование только
    исходного файла из 500 строк. Ассемблирование программы из 500
    строк занимает значительно меньше времени, чем программы из 5000
    строк. Этап редактирования связей все так же будет занимать
    относительно немного времени, особенно по сравнению с
    ассемблированием большой программы. Уменьшение размеров отдельных
    модулей позволяет более быстро осуществить процесс
    редактирования-ассемблирования.
 
      Другая причина разбиения программы на меньшие модули связана с
    этапом ее разработки. В случае больших программных средств в их
    разработке, как правило, участвуют несколько человек. Если имеется
    один исходный файл, то отдельные программисты вынуждены работать с
    ним по очереди. Такой подход очень быстро становится неудобным.
 
      И последняя из причин создания модульных программ заключается в
    возможности их универсального использования. Предположим, что
    созданная вами программа включает несколько подпрограмм. Если вы
    хорошо справились с этим, то каждая из подпрограмм выполняет у вас
    особую функцию с хорошо документированной спецификацией входа и
    выхода. Через некоторое время при написании новой программы вы
    захотите использовать в ней ту же самую подпрограмму. Если эта
    подпрограмма оформлена в виде отдельного программного модуля, то
    включить ее в новую программу не составляет труда. В противном
    случае вам придется как-то выделить этот фрагмент из исходной
    программы и перенести его в новую программу. После одной-двух
    попыток вам, возможно, захочется поискать другой способ.
 
      Разбиение программы на модули требует от программиста ряда
    действий. Во-первых, нужно тщательно продумать, как ваша программа
    будет строиться из меньших компонентов. Во-вторых, нужно определить
    как входные, так и выходные параметры этих меньших программ. И
    наконец, должна быть возможность обмена данными между программными
    модулями. Первые два пункта относятся к основам программирования и
    мы их здесь касаться не будем. Последний же пункт связан с
    ассемблированием и редактором связей, поэтому его мы рассмотрим.
 
      Если разработанная вами программа состоит из нескольких
    модулей, то в этом случае у ведущей, или основной программы должна
    быть возможность вызывать эти подпрограммы. Это реализуется
    командой CALL, имеющей один операнд - метку соответствующей
    подпрограммы. Во всех рассмотренных до сих пор примерах
    подпрограмма была частью того же самого программного модуля, так
    что ассемблеру было точно известно, каким будет адрес подпрограммы
    в момент ее выполнения. Это позволяло ассемблеру определять
    правильное значение смещения для поля адреса в команде.
 
      Теперь мы сталкиваемся с ситуацией, когда ассемблирование
    подпрограммы осуществляется отдельно от ассемблирования команды
    CALL. Это означает, что ассемблер не может определить правильный
    адрес для процедуры вызова, т.е. из-за того, что ассемблирование
    подпрограммы и основной программы осуществляется раздельно, у
    ассемблера нет способа предсказать правильное значение адреса.
    Однако эту задачу может выполнить программа LINK. Определение
    адресов производится на этапе редактирования связей. Так как при
    работе программы LINK ее входом являются все программные модули, то
    редактору связей известно, где будет конец каждой из подпрограмм.
    После этого редактор связей может определить значения тех адресов,
    которые были известны ассемблеру.




Содержание раздела