Microsoft C

У версії 5.0 свого компілятора Сі корпорація Microsoft вивела на ринок PC високий рівень оптимізації коду. Microsoft приділяє багато уваги аналізу циклів. C 5.0 - єдиний з розглянутих компіляторів, що виконує винесення інваріантного коду і сьогоденне видалення змінних індукції циклів. Компілятор Microsoft C 5.0 чудово використовує регістри, намагаючись мінімізувати звертання до пам'яті в тілі циклу . Простий приклад циклу в коді тесту демонструє ступінь оптимізації циклів, який виконує Microsoft C 5.0. Компілятор застосовує зниження потужності і цілком видаляє константне множення, виявляє кінцевий стан змінних, і поміщає в регістри всі змінні всередині циклу. C 5.0 видаляє цикл for і генерує код тільки з метою установки кінцевого стану змінної - індексу циклу й оператора, включеного в цикл. Компілятор також добре використовує регістри. Увага фірми Microsoft до оптимізації винагороджується при роботі тесту виконання. Він виконується за час, що є кращим чи близько до кращого по кожній категорії.

WATCOM

Новітній суперник, що завойовує позиції на ринку компіляторів C - WATCOM C 6.0 (див. Product Watch, Philip N. Hisley, за цей місяць). C 6.0 виробляє компактний код, що чудово використовує трохи обмежений комплект регістрів сімейства 80x86. Крім виконання базових прийомів оптимізації, він підтримує зниження потужності і видалення недосяжного коду і загальних підвиразів. У той час, як Microsoft досягає поліпшення коду завдяки оптимізації циклів, WATCOM збільшує швидкість шляхом зменшення керуючих заголовків викликів функцій до їхнього абсолютно мінімального розміру. Він досягає цього, шляхом переважної передачі параметрів через регістри, а не через стек. WATCOM дуже добре видаляє недосяжний код. C 6.0 не тільки видалив непотрібні присвоювання і недосяжний код усередині функції, але він також видалив пролог і епілог функції і згорнув усю функцію до простого повернення, приписавши ім'я функції до інструкції повернення основної функції. На завершення всього, компілятор видалив локальний виклик функції. Наскільки C 6.0 витончений у знищенні марної функції, настільки ж він безпомічний при видаленні марного присвоювання, що дублюється. Найбільш важлива область, за яку WATCOM C 6.0, як і Optimum-C, не зміг узятися, була оптимізація циклів. Він не підтримує винесення інваріантного коду і видалення змінної індукції циклів. Хоча C 6.0 не виконує розгортання циклів в окремі команди, він (також як Datalight Optimum-C і Computer Innovations C86Plus) використовує команду REP/STOSW процесорів 80x86 для ініціалізації тестового масиву, завдяки чому видаляє цикл. Прекрасна генерація коду в WATCOM, зокрема, розумне використання регістрів, дає йому дуже важлива перевага. Він переміг у більшості тестів, що інтенсивно використовують процесор, і при цьому виконувався для великої моделі в кращий час, ніж більшість інших компіляторів для малої моделі. До слабких сторін WATCOM можна віднести введення/виведення файлів, використання getc і putc. Тут він близький до найгірших компіляторів.


Лекція 4

1. Поняття "об'єктного файлу" та "виконуваного модуля"

2. Архітектура виконуваного модуля

3. Поняття "компонування"

4. Види заголовків виконуваних файлів та огляд видів форматів виконуваних модулів та об’єктних файлів

1. Поняття "об’єктного файлу" та "виконуваного модуля"

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

Виконуваним модулемназивається такий об’єктний файл, якому передує так званий заголовок, який вказує, яким чином операційна система повинна виконувати цей код.

2. Архітектура виконуючого модуля

 

OBJ-модуль - більш наближений до виконавчих форм, але ще не готовий до виконання. Крок компонування включає перетворення OBJ-модуля в EXE (здійсненний) модуль, що містить машинний код. Програма LINK, що знаходиться на диску DOS, виконує наступне:

1. Завершує формування в OBJ-модулі адрес, що залишився невизначеним після асемблювання. В багатьох наступних програмах такі адреси асемблер відмічаєяк -і-іR.

2. Компонує окремо, якщо необхідно, більше одного асемблюваного модуля в одну завантажувальну (здійсненну) програму; можливо дві чи більше асемблерних програм, або асемблерну програму з програмами, написаними на мовах високого рівня, таких як Паскаль чи Бейсік.

3. Ініціалізує EXE-модуль командами завантаження для виконання.

Після компоновки OBJ-модуля (одного чи більше) у EXE-модуль, можна виконати EXE-модуль будь-яку кількість раз. Але, якщо необхідно внести деякі зміни в EXE-модуль, варто скорегувати вихідну програму, асемблювати її в інший OBJ-модуль і виконати компоновку OBJ-модуля в новий EXE-модуль. Навіть, якщо ці кроки поки залишаються незрозумілими, ви зрозумієте, що, одержавши небагато навичок, весь процес підготовки EXE-модуля буде доведений до автоматизму. Помітьте: визначені типи EXE-програм можна перетворити в дуже ефективні COM-програми. Якщо в результаті асемблюваня не виявлено помилок, то cлідуючий крок - компоновка об'єктного модуля. Файл EXASM1.OBJ містить тільки машинний код у шістнадцятковій формі. Оскільки програма може завантажуватися майже в будь-яке місце пам'яті для виконання, тому асемблер може не визначити всі машинні адреси. Крім того, можуть використовуватися інші (під) програми для об'єднання з основними. Призначенням програми LINK є завершення визначення адресних посилань і об'єднання (якщо потрібно) декількох програм. Для виконання можна також створювати COM-файли. Прикладом часто використовуваного COM-файлу є COMMAND.COM. Програма EXE2BIN.COM в оперативній системі DOS перетворить EXE-файли в COM-файли. Фактично ця програма створює BIN (двійковий) файл, тому вона і називається "перетворювач EXE у Вin (EXE-to-BIN)". Вихідний Вin-файл можна переназвати у COM-файл.

РОЗХОДЖЕННЯ МІЖ ПРОГРАМАМИ В EXE і COM-файлах

Незважаючи на те, що EXE2BIN перетворить EXE-файл у COM-файл, існують визначені розходження між програмою, виконуваної як EXE-файл, і програмою, виконуваної як COM-файл.

Розмір програми.

EXE-програма може мати будь-який розмір, у той час як COM-файл обмежений розміром одного сегмента і не перевищує 64ДО. COM-файл завжди менший, ніж відповідаючий EXE-файл; одна з причин цього - відсутність у COM-файлі 512-байтового початкового блоку EXE-файлу.

Сегмент стека.

У EXE-програмі визначається сегмент стека, у той час як COM-програма генерує стек автоматично. У такий спосіб при створенні асемблерної програми, яка буде перетворена в COM-файл, стек повинен бути опущений.

Сегмент даних.

У EXE програмі звичайно визначається сегмент даних, а регістр DS ініціалізується адресою цього сегмента. У COM-програмі всі дані повинні бути визначені у сегменті коду. Нижче буде показаний простий спосіб рішення цього питання.

Ініціалізація.

EXE-програма записує нульове слово в стек та ініціалізує регістр DS, тому що COM-програма не має ні стека, ні сегмента даних, де ці кроки відсутні. Коли COM-програма починає працювати, усі сегментні регістри містять адресу префікса програмного сегмента (PSP), - 256-байтового (тичина. 100) блоку, що резервується операційною системою DOS безпосередньо перед COM чи EXE програмою в пам'яті. Оскільки адресація починається з точки зсуву 100 від початку PSP, то в програмі після оператора SEGMENT кодується директива ORG 100H.

Обробка.

Для програм у EXE і COM форматах виконується асемблювання для одержання OBJ-файлу, і компоновка для одержання EXE-файлу. Якщо програма створюється для виконання як EXE-файл, то її вже можна виконати. Якщо ж програма створюється для виконання як COM-файл, то компоновщиком буде видане повідомлення:

Warning: No STACK Segment

(Попередження: Сегмент стека не визначено)

Це повідомлення можна ігнорувати, тому що визначення стека у програмі не передбачалося. Для перетворення EXE-файлу у COM-файл використовується програма EXE2BIN. Припустимо, що EXE2BIN мається на дисководі A, а скомпонований файл по імені CALC.EXE - на дисководі B. Уведіть EXE2BIN B:CALC,B:CALC.COM. Оскільки перший операнд завжди припускає EXE файл, то можна не кодувати тип EXE. Другий операнд може мати інше ім'я (CALC.COM). Якщо не вказувати тип COM, то EXE2BIN прийме за замовчуванням тип BIN, який згодом можна перейменувати в COM. Після того як перетворення буде виконано, можна видалити OBJ і EXE-файли. Якщо вихідна програма написана для EXE-формату, то можна, використовуючи редактор, замінити команди у вихідному тексті для COM файлу.

ОСНОВНІ ПОЛОЖЕННЯ НА ПАМ'ЯТЬ

- Обсяг COM-файлу обмежений 64ДО.

- COM-файл менший, ніж відповідний EXE-файл.

- Програма, написана для виконання в COM-форматі не містить стека і сегмента даних і не вимагає ініціалізації регістра DS.

- Програма, написана для виконання в COM-форматі, використовує директиву ORG 100H після директиви SEGMENT для виконання з адреси після префікса програмного сегмента.

- Програма EXE2BIN перетворить EXE-файл у COM-файл, обумовлений указівкою типу COM у другому операнді.

- Операційна система DOS визначає стек для COM-програми або наприкінці програми, якщо дозволяє розмір, або ж наприкінці пам'яті.

 

3. Поняття "компонування"

 

Об'єктний лінкер призначений для створення виконавчих файлів з об'єктних файлів, сформованих MASM чи компіляторами C або PASCAL. LINK формує пересувний виконавчий код, позначений інформацією переміщення, використовуючи яку, MS-DOS зможе завантажити в пам'ять і виконати відповідну програму. LINK може формувати програми, що містять понад 1М коду і даних. Сприймаючи на вхід 2 файли, LINK може формувати 2 вихідних файли, як показано на рис.3.1.

 

Рис. 3.1. Робота LINK.

 

Розширення імен файлів, показані на малюнку, приймаються за замовчуванням. Об'єктний файл містить об'єктні модулі програмних сегментів, сформовані MASM чи компілятором мови високого рівня. Бібліотеки містять набори модулів, на яких можуть посилатися програмні сегменти в об'єктному файлі. Бібліотечні файли формуються за допомо- гою утиліти LIB. Основним результатом роботи LINK є виконавчий файл, що містить програму у виді, придатному для завантаження в пам'ять і виконання. Деякі особливості формування виконавчого файлу описані в п.3.4. Файл плану є необов'язковим і містить, якщо він формується, деяку діагностичну і службову інформацію, яка потім за допомогою утиліти MAPSYM може бути використана в процесі налагодження програми. Файл плану містить імена, завантажувальні адреси і довжини усіх сегментів програми. Крім того, сюди входять імена і завантажувальні адреси груп у програмі, адреса крапки входу, а також повідомлення про можливі помилки.

Якщо задана опція /MAP, у файл включаються імена загальних символів і їхні завантажувальні адреси. Якщо задані опції /HIGH чи /DSALLOCATE і обсяг програми та даних у сукупності не перевищує 64ДО, план може містити символи з незвичайно великими адресами сегментів. Ці адреси відбивають змінні, розташовані нижче дійсного початку сегмента.

Приклад:

FFF0:0A20 TEMP

Адреса TEMP - 00:920h.

Необхідно мати те, через що, крім двох вихідних файлів, LINK може формувати тимчасовий файл з ім'ям VM.TMP. Це відбувається в тому випадку, коли лінкеру не вистачає оперативної пам'яті. Створення файлу VM.TMP супроводжується повідомленням на консолі і завжди здійснюється у поточному підзаголовку. У цьому випадку не можна використовувати опцію /PAUSE і знімати дискету, якщо вона знаходиться на активному драйві, до того, як LINK не знищить файл VM.TMP. Не реко- мендується створювати в поточному підзаголовку файл із таким ім'ям, що у цьому випадку може бути зіпсований.