Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СП_від_Мархивки.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
498.69 Кб
Скачать

Завантажувачі Функції завантажувачів.

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

Функції завантажувача наступні:

  • розподіл - виділення місця для програм у пам'яті;

  • завантаження - фактичне розміщення команд і даних у пам'яті;

  • зв'язування - дозвіл перехресних символьних посилань між об'єктами;

  • переміщення - настроювання усіх величин у модулі, що залежать від фізичних адрес відповідно до виділеної пам'яті;

  • ініціалізація – встановлення початкових значень регістрів та передача керування на стартову адресу програми.

Функції завантажувача не обов'язково повинні виконуватися саме в тій послідовності, у якій вони подані. Деталізуємо ці функції.

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

Функція завантаження зводиться до зчитування образу програми з диска (чи іншого зовнішнього носія) в оперативну пам'ять.

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

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

Функція переміщення необхідна тому, що програма на будь-якій мові розробляється в деякому віртуальному просторі адрес, у якому адресація ведеться відносно початку програмної секції. При написанні програми і при її трансляції, як правило, невідомо, по якій адресі пам'яті буде розміщена програма (де система знайде вільну ділянку пам'яті для її розміщення). Усі величини в програмі, особливо операнди команд з елементами прямої адресації, повинні бути прив'язані до реальних адрес і відповідно модифіковані з урахуванням адреси завантаження програми у пам’ять.

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

Функція ініціалізації передбачає встановлення початкових значень регістрів та передачу керування на стартову адресу програми. Важливим нюансом ініціалізації є встановлення вершини програмного стеку.

Основні типи завантажувачів.

Абсолютні завантажувачі використовуються для завантаження у пам’ять, так званих, абсолютних програм. Функції такого завантажувача:

  • функція розподілу не виконується, тому що адреса завантаження заздалегідь відома;

  • функція завантаження виконується, але вона гранично проста;

  • функція зв'язування не виконується, оскільки всі адреси програми відомі заздалегідь;

  • функція переміщення виключається;

  • функція ініціалізації залишається.

Частка абсолютних програм у загальній масі програмного забезпечення мізерно мала. Абсолютними можуть бути системні програми найнижчого рівня, програми, записувані в ПЗП, програми для вбудованих пристроїв і т.п.

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

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

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

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

П ереміщення в налаштовуючому завантажувачі. Прийняті в цьому завантажувачі методи дозволяють легко реалізувати настроювання реальних адрес, заданих відносно початку програми. Сутність методу переміщення полягає в тому, що кожному слову коду програми (розмір слова звичайно дорівнює розміру реальної адреси) ставиться у відповідність "біт переміщення". Значення цього біта 0 або 1 є ознакою непереміщуваного або переміщуваного слова. Якщо слово є непереміщуваним, то воно залишається завантажувачем без змін. Якщо слово є переміщуваним, то до його значення додається стартова адреса модуля в оперативній пам'яті. Біти переміщення можуть упаковуються в байти.

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

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

  • розмір модуля – запис початку;

  • машинні коди – записи тіла;

  • список імен текучого модуля, до яких можливі звертання ззовні – записи визначення;

  • список зовнішніх імен, до яких є звертання в даному модулі – записи посилання;

  • інформація про розміщення в модулі переміщуваних даних – записи модифікатори.

Один з варіантів організації об'єктного модуля описується нижче.

Об'єктний модуль складається з записів чотирьох типів. У кожнім записі перший байт містить ідентифікатор типу запису, наступних 2 байти - розмір запису. Кількість і формат решти байтів запису визначається його типом. Повернемось до записів зв’язувань і записів переміщень.

Запис зв'язувань містить один або декілька елементів таблиці зовнішніх імен(EXTTAB). Елемент цієї таблиці має наступний формат:

А семблери і транслятори формують елементи таблиці зовнішніх імен при опрацюванні директив типу SEGMENT, PUBLIC, EXTRN.

Запис переміщень(записи модифікатори) містить один або декілька елементів таблиці переміщень. Кожен елемент цієї таблиці описує один елемент коду програми, що вимагає настроювання, і має наступний формат:

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

Нехай існує вираз ADDR1 - ADDR2

  • Якщо ADDR1 і ADDR2 є відносними іменами того самого сегмента SEGM , то адресний вираз буде абсолютним, тому що його значення: SEGM+ADDR1 - (SEGM+ADDR2) не залежить від адреси сегмента. Для такого виразу елемент таблиці переміщень не формується.

  • Якщо ADDR1 є ім'ям усередині сегменту SEGM, а ADDR2 - абсолютна адреса, то значення виразу буде відносним і потребує переміщення. У кодове представлення цього виразу записується різниця між відносною адресою в сегменті ADDR1 і абсолютним значенням ADDR2. Для такого виразу формується елемент таблиці переміщень: адреса → SEGM → + → довжина. Завантажувач додасть до вмісту коду значення адреси сегменту SEGM.

  • Якщо ADDR1 є зовнішнім ім'ям, а ADDR2 - абсолютна адреса, то значення виразу також є відносним. У кодове представлення цього виразу записується абсолютне значення ADDR2. Елемент таблиці переміщень для такого виразу буде містити:

адреса → ADDR1 → + → довжина

  • Якщо ADDR1 і ADDR2 є зовнішніми іменами, то значення виразу є відносним. У кодове представлення цього виразу записують 0 і для нього формуються два елементи таблиці переміщень:

адреса → ADDR1 → + → довжина

адреса → ADDR2 → - → довжина

При завантаженні до нульового значення буде додано значення зовнішнього імені ADDR1, а потім вирахуване значення зовнішнього імені ADDR2.

Можливі варіанти складніших адресних виразів. Подібним чином визначається тип результуючого виразу і формується або не формується елемент таблиці переміщень.