Складання програми - Студопедія

Ми про типи виконуваних модулів, але не говорилося ні слова про те, як ці модулі виходять. Взагалі кажучи, спосіб отримання модуля, що завантажується, різний в різних ОС, але в даний час у всіх широко поширених системах цей процес виглядає приблизно однаково. Це пов'язано, передусім, про те, що це системи використовують одні й самі мовні процесори.

Окрім посилань на власні об'єкти, об'єктний модуль має право посилатися на об'єкти, визначені в інших модулях. Типовий приклад такого посилання - звернення до функції, визначеної в іншому файлі вихідного тексту. Найпростіший спосіб відстежувати такі посилання – зібрати їх у таблицю.

модулів

Таких таблиць має бути дві: зовнішні об'єкти, куди посилається модуль, і об'єкти, визначені всередині модуля, куди можна посилатися ззовні. Зазвичай з кожним таким об'єктом асоціюється ім'я, яке називається глобальним символом. Як правило, це ім'я збігається з ім'ям відповідної функції або змінної у вихідній мові.

Отже, типовий об'єктний модуль містить такі структури даних:

  • Таблицю переміщень, тобто. таблицю посилань на об'єкти, що переміщуються всередині модуля.
  • Таблиця посилань на зовнішні об'єкти. Іноді це називається таблицею чи списком імпорту.
  • Таблиця об'єктів, визначених тут, на які можна посилатися з інших модулів. Іноді її називають переліком експорту.

Іноді цю таблицю поєднують із попередньою і називають усе це таблицею глобальних символів. У цьому випадку для кожного символу доводиться вказувати, чи визначений він у даному модулі чи ні, а якщо визначений, то як.

  • Різну службову інформацію, таку, як ім'я модуля, програму, яка його створила (наприклад, рядок"gcc compiled")
  • Налагоджувальну інформацію.
  • Власне код та дані модуля. Як правило, цю інформацію розбито на іменовані секції. Уmasm/tasmтакі секції називаютьсясегментами, в DEC'івських таUNIX'ових асемблерах -програмними секціями (psect (12)). У готовій програмі весь код або дані, що належать до однієї секції, збираються разом.

Великі програми часто складаються із сотень і більше окремих модулів. Крім того, існують різні пакети підпрограм, які також складаються з великої кількості модулів. Один із таких пакетів використовується практично в будь-якій програмі мовою високого рівня – це так звана стандартна бібліотека. Для вирішення проблем, що виникають при підтримці порядку в наборах з великої кількості об'єктних модулів, ще на зорі обчислювальної техніки були придумані бібліотеки об'єктних модулів.

Бібліотека, як правило, представляє послідовний файл, що складається із заголовка, за яким послідовно укладені об'єктні модулі. У заголовку міститься така інформація:

  • Список всіх об'єктних модулів зі зміщенням кожного модуля від початку бібліотеки. Це потрібно для того, щоб можна було легко знайти потрібний модуль.
  • Список всіх глобальних символів, визначених у кожному з модулів, із зазначенням, у якомусамемодулі він був визначений.

Лінкер зазвичай збирає в програму всі об'єктні модулі, які були йому задані в командному рядку, навіть якщо на цей модуль не було жодного посилання. З бібліотечними модулями він поводиться дещо інакше.

Деякі архітектури процесорів підтримують динамічно пересоблювані програми, у яких все налаштування модуля винесено в окрему таблицю. У цьому випадку модульможе бути прилінковано одночасно до кількох програм, використовувати одночасно різні копії сегмента даних, і кожна інкарнація модуля при цьому навіть не підозрюватиме про існування інших. Прикладом такої архітектури є Pascal-системаLilith, розроблена Ніклаусов.

Взагалі, серед сучасних ОС досить багато систем, які використовують той чи інший спосіб збирання під час завантаження. Таким чином влаштований, наприклад,Novell Netware.

Складання при завантаженні істотно уповільнює процес завантаження програми, але спрощує, з одного боку, поділ коду, а з іншого боку - розробку програм. Дійсно, з класичного циклу внесення зміни до програми: редагування тексту – перекомпіляція – перескладання – перезавантаження (програми, не обов'язково всієї системи), випадає ціла фаза. У разі великої програми може бути тривала фаза. У випадкуNovell Netwareвирішальним є перша перевага, у разі систем реального часу однаково важливі обидва.

У системахMS WindowsтаOS/2використовується спосіб завантаження, проміжний між збиранням в момент завантаження та збиранням заздалегідь. Завантажувальний модуль у цих системах може бути повністю самодостатнім, а може містити посилання на інші модулі, званіDLL (Dynamically Loadable Library - бібліотека, що динамічно завантажується). Найкраще в цій схемі те, що модуль, за власним бажанням, може вибирати різні бібліотеки. Єдине обмеження полягає в тому, що такі бібліотеки мають бути сумісними за викликами.

Наприклад, програмаCorelDRAW!може імпортувати та експортувати зображення в різних видах, починаючи від власного внутрішнього формату .CDR або Windows Bitmap, і закінчуючисильнозапакованим форматом Jpeg або спеціалізованими форматами, на зразок Targa-файлів. Імпорт та експорт кожного формату виконується окремою DLL.

DLL на перший погляд здаються зручним засобом поділу коду і створення програмних модулів, що окремо завантажуються, але вони мають дуже серйозне обмеження.

Це обмеження проявляється, коли ми намагаємося створити в багатопроцесному середовищі DLL для роботи з ресурсом, що розділяється, наприклад багатовіконну графічну систему для роботи декількох завдань з терміналом, що розділяється. DLL, що працює з даними, що поділяються, не зможе обробляти одночасно два виклики з різних процесів. Це створить багато проблем, вирішення яких або неможливе в принципі, або пов'язане з великими незручностями. Тому в багатопроцесному середовищі нам доведеться виділити віконну систему в окремий процес і оформляти звернення до неї не як звичайні виклики процедур, а як надсилання повідомлень засобами міжпроцесної взаємодії. Наприклад, таким чином реалізована мережева віконна системаX Windows, реалізована на всіх ОС сімействаUnixта багатьох інших системах.

Кошти міжпроцесного взаємодії будуть докладніше обговорюватися пізніше, тепер ми скажемо лише, що це кошти у сучасних ОС за потужністю не поступаються прямому виклику процедури. Існує навіть модель взаємодії, яка так і називається -RPC (Remote Procedure Call- Видалений виклик процедури). Звісно, ​​таке використання цих коштів супроводжується більшими накладними витратами, ніж прямий виклик; натомість ми отримуємо набагато більшу свободу. Наприклад, ми можемо звертатися до програми, що виконується іншому процесорі чи взагалі іншій машині, або розділяти загальний ресурс (наприклад, загальну базу даних) з іншим процесом.

Томуте, що уMS Windowsвиробляється з допомогою DLL, у більшості сучасних ОС реалізується засобами межпроцессного взаємодії.

Крім того, використання DLL сильно уповільнює процес завантаження програм і дещо знижує загальну продуктивність систем із віртуальною пам'яттю. Системи сімействаUnixвикористовують монолітний завантажувальний модуль та/або бібліотеки, що розділяються, помітно швидше, ніжOS/2іWindows NT, що використовують DLL.

Чи не знайшли те, що шукали? Скористайтеся пошуком: