Л.Е. Карпов - Системы программирования (1114903), страница 17
Текст из файла (страница 17)
Это делает несовместимыми друг с другомпрограммы, подготовленные в рамках разных операционных систем (например,программы, подготовленные для систем Windows и Linux, имеют разные по структуретаблицы трансляции адресов, хотя и те, и другие должны выполняться на одной и тойже аппаратуре – процессоре персонального компьютера).
В то же время вынесениезагрузчика из состава систем программирования в состав операционных систем делаетструктуру этой таблицы более общей, не зависящей от конкретной системыпрограммирования. В противном случае, программы, подготовленные системамипрограммирования компании Borland, нельзя было бы выполнять в операционнойсистеме, предназначенной для работы с системами программирования компанииMicrosoft.Вынесение загрузчиков в операционные системы имеет еще один очень важныйсмысл.
Современные вычислительные комплексы могут иметь сложные аппаратноуправляемые структуры памяти. Методы трансляции адресов могут основываться насегментной, страничной или сегментно-страничной организации памяти. Полноевладение ситуацией может обеспечить только операционная система, причем только вмомент непосредственного занесения программы в память. Это означает, что загрузчиксистемы программирования в принципе не способен решить все проблемымодификации адресов, поскольку он не может знать точных характеристикконфигурации аппаратных средств и состояния внутренних таблиц подсистемыуправления памятью операционной системы в момент, когда программа начнетвыполняться.
Загрузчик, который выполняет трансляцию адресов в момент запускапрограммы, называется настраивающим загрузчиком.3.6. Техника работы с библиотекамиСущественной особенностью систем программирования является наличие иноменклатура библиотек подпрограмм. По техническому составу библиотеки делятсяна две категории: библиотеки функций исходного языка и библиотеки функцийоперационной системы, в составе которой должна будет работать обрабатываемаяпрограмма.
Эта операционная система может отличаться от той, в составе которойфункционирует сама система программирования.Некоторую часть библиотеки, а именно описания входящих в библиотекикомпонентов, необходимо передавать компилятору, чтобы во время компиляциипрограмм, ссылающихся на библиотечные элементы, компилятор мог проверять,например, соответствие списков формальных и фактических параметров.
Фактическиепараметры задаются в компилируемых программах, а формальные параметрыописываются в заголовках библиотечных процедур. С другой стороны, библиотекисами формируются компиляторами, поскольку реализации библиотечных элементовописываются на языках программирования.Библиотеки делятся на статические и динамические по выбору того момента,когда система программирования извлекает из них элементы.3.6.1. Статические библиотекиСтатические библиотеки фактически представляют собой процедуры и функции,встраиваемые внутрь программ, подготавливаемых системами программирования наэтапе обработки этих программ. Все статические библиотеки подключаются к63программам, готовящимся к выполнению, ровно один раз в момент формированияредактором связей полной программы. После подключения компоненты статическойбиблиотеки становятся неотъемлемой частью программы и в дальнейшемраспространяются вместе с нею.
Программа, к которой уже подключены компонентыстатической библиотеки, приобретает независимость от самой этой библиотеки. Если вбиблиотеку будут внесены изменения, вносить какие-либо параллельные изменения впрограмму, использующую исправленную библиотеку не требуется. Связь программыи библиотеки после подключения этой библиотеки к программе разрывается. Этосвойство статических библиотек является их несомненным преимуществом.Другой стороной разрыва связи программы и библиотеки в момент ихобъединения является трудоемкость исправления программ в случае, если внесениеизменений в библиотеку объясняется исправлением существовавшей в ней ошибки.
Этатрудоемкость связана с необходимостью произвести повторную полную сборкупрограммы из объектных модулей и исправленных библиотечных компонентов.Статическое подключение компонентов библиотек к объектным модулям ведетк существенному росту объемов готовых программ. В современных условиях, когдабиблиотеки достигли высокой степени развития, доля компонентов библиотек в объемеготовых программ уже превышает половину этого объема. Поскольку некоторымисистемными и стандартными библиотеками пользуются почти все программы, размерынепроизводительно используемой памяти, как в архивах программ, так и в памятивычислительных машин при выполнении программ, могут быть очень большими.3.6.2. Динамически загружаемые библиотекиКомпоненты динамических библиотек (динамически загружаемые компоненты ибиблиотеки) подключаются к программам во время выполнения этих программ.
В этомсостоит основное отличие динамических библиотек от статических. Компонентыдинамических библиотек не связаны с программами, которые к ним обращаются, ираспространяются отдельно от них.Некоторые динамические библиотеки подключаются к программам в самомначале выполнения программы при ее записи в оперативную память вычислительноймашины. Какой-либо связи с тем, будет в программе реальное обращение ккомпонентам библиотеки или нет, здесь не возникает.
Другие библиотеки попадают воперативную память только тогда, когда происходит реальное обращение к какомунибудь одному из их компонентов (к какой-либо процедуре или функции из этихбиблиотек). Освобождение памяти для разных библиотек также происходит поразному. Память может освобождаться либо после завершения выполнения всейпрограммы, либо по указанию главной программы, которая просигнализирует, чтонекоторая библиотека больше использоваться ее не будет. Возможен и вариант, когдапамять, занимаемая динамическим подгруженным компонентом, будет освобожденанепосредственно после завершения выполнения этого компонента.Загрузка при обращении к компоненту библиотеки имеет определенныепреимущества перед загрузкой при начале выполнения программы.
Памятьвычислительной машины при таком методе загрузке библиотек используется болеерационально, но этот метод сложнее для реализации. Он требует либо существенногоусложнения операционной системы, либо внесения в программы специальных указанийдля динамической загрузки, поскольку только разработчик программы может точнознать, когда потребуется загрузка в память той или иной библиотеки (или какого-либо64компонента библиотеки). Точно также только разработчик программы может точнознать, когда можно освободить память от используемой библиотеки.Загрузка при начале выполнения программы менее экономно расходуетоперативную память, но проще реализуется, поскольку может быть полностьюавтоматизирована, а задача такой динамической загрузки может быть решенакомпоновщиком программ (редактором связей).
Для этого достаточно в заголовокпрограммы добавить перечень всех используемых в программе библиотек. Имея такойперечень, который обычно передается компоновщику в качестве одного из параметровего запуска, он может обеспечить загрузку всех библиотек в память перед началомработы основной программы.Современные системы программирования обычно допускают оба метода работыс динамическими библиотеками, а решение по выбору конкретного методапринимается разработчиком программы. В общем случае, для разных библиотек можновыбирать разные методы. Выбор зависит от размеров библиотек и количестваобращений к их компонентам.Загрузка динамических библиотек в оперативную память, освобождение этойпамяти, а также связывание основной программы и ее данных с компонентамибиблиотек (программами и данными) выполняется динамическим загрузчиком. Этотзагрузчик входит в состав операционной системы и контролирует все обращения кдинамически загружаемым библиотекам и модулям, считает эти обращения, а такжеосвобождает память, когда количество действующих обращений оказывается равнымнулю.
Передача функции загрузчика из системы программирования в операционнуюсистему позволила обеспечить повторное использование библиотечных компонентовпри обращении к ним нескольких различных программ. Если динамическая библиотекауже загружена в память, нет необходимости загружать ее повторно. Загрузчик способенотслеживать двойные обращения и обеспечивать доступ к библиотечным компонентамвсем работающим программам.Выполнение функций динамическим загрузчиком возможно только в томслучае, если загружаемая библиотека или объектный модуль имеют определеннуюструктуру, содержащую в себе информацию, необходимую для трансляции адресов.Большинство современных редакторов связей могут работать в режиме формированиятаких библиотек и модулей. Непосредственная загрузка динамических объектов впамять выполняется настраивающим загрузчиком, при этом их программная частьоказывается доступной всем исполняемым программам, а часть, содержащая данныедублируется для каждой исполняемой программы так, как будто она являетсяединственной программой, использующей динамически загружаемые объекты.Формат файлов динамических библиотек полностью зависит от операционнойсистемы, о н близок к фор мату исполняемых файлов.
В эти файлы (так же, как и встатических библиотеках) включены описания компонентов, что позволяеткомпиляторам автоматически контролировать операторы обращения к библиотечнымкомпонентам. В то же время каких-либо команд обращения к этим компонентамкомпиляторы для динамических библиотек вставить не могут. Вместо них в программывставляются команды обращения к функциям операционной системы, которыеобеспечивают обращения к компонентам динамических библиотек. Эти команды могутвставляться автоматически, что предполагает проведение динамической загрузки вмомент запуска основной программы, либо “вручную” самим разработчикомпрограммы, что обеспечит реализацию динамической загрузки в момент реального65обращения к библиотечным компонентам.
Компоненты, к которым завершены всеобращения, могут удаляться операционной системой из памяти машины. Вновь онипопадают в память только после очередного реального обращения к ним.Динамические библиотеки имеют множество преимуществ перед статическими.Их составляющие не должны включаться в состав исполняемых файлов программ, чтозначительно сокращает их размеры. Этого преимущества удается добиться за счетразработки специального механизма операционной системы, который выполняетподключение фрагментов одних программ к другим в момент их выполнения.Известным недостатком динамических библиотек является зависимостьпрограммного обеспечения от библиотечных объектов, непосредственно не связанныхс этим обеспечением, то есть зависимость программ пользователей от неизвестных имдинамических библиотек.