4. Види компіляторів C
Borland International
Вихід компілятора Turbo C являє собою розумний, але не дуже оптимізований код. Крім згортки констант, видалення зайвих завантажень регістрів і алгебраїчних спрощень, компілятор виконує тільки зниження потужності, видалення недосяжного коду і розміщення змінних у регістрах. Він не підтримує інші загальні методи оптимізації, такі як видалення зайвих збережень, загальних підвиразів і змінні індукції циклу, а також винесення інваріантного коду. Turbo C розумно керує прологом і епілогом функцій і використанням регістрів, засилаючи в стек і витягаючи тільки ті регістри, що явно використовуються усередині тіла функції.
Computer Innovation Inc
Компілятор C86Plus виробляє чудовий код із середнім рівнем оптимізації. Він виконує базові прийоми оптимізації, такі як згортка констант і розмноження копій. Однак він не виконує розмноження констант для видалення зайвих збережень. Хоча компілятор успішно виконує алгебраїчні спрощення, він породжує зайві інструкції через те, що розміщає результати в регістрах, замість того, щоб поміщати їх у змінні. Цей ефект виявляється в том, що при розміщенні змінних у регістрах починаються спроби перерозміщення, тому що при виконанні декількох операторів результати в дійсності повинні бути привласнені відповідним змінним. Хоча C86Plus успішно справляється зі згорткою явних присвоювань, що дублюються, в одне присвоювання, видалення зайвих збережень він виконує хитливо. Він не виконує істотну оптимізацію циклів.
Datalight Inc
З появою Optimum-C Datalight стала одним з перших постачальників, що запропонували оптимізований компілятор. Хоча набір тестів не підтвердив наочно претензії Datalight на глобальну оптимізацію, Optimum-C спрацював так добре в деяких фрагментах тесту, що продемонстрував слабкі фрагменти набору, які вимагають змін для удосконалення бажаної перевірки. Наприклад, у першій версії функції jump-compression не поверталося значення, що робило всі обчислення і присвоювання у функції зайвими. Optimum-C виявив це і видалив велику частину коду функції, включаючи ланцюжок переходів. У тесті розмноження констант і копій Optimum-C визначив, що присвоювання i5 в обох умовних операторах є зайвим стосовно наступних присвоювань. Компілятор видалив не тільки ці присвоювання, але й умовні оператори. Незадовільним виявилося видалення зайвих збережень значень регістрів. Optimum-C - єдиний компілятор, що намагався виконати глибоке видалення загальних виражень. Перевірка згенерованого коду показала, що загальне вираження i5+i2 було переміщено вище першого базового блоку умовного оператора, але не було вилучено з другого. Поза обмеженнями на стандартне використання регістрів, що накладаються сімейством мікропроцесорів 80x86, Optimum-C розумно використовує регістри. У функції jump-compression кожен переданий параметр був поміщений у регістр. Усередині тіла функції не було посилань у пам'ять, крім початкового засилання в регістри. Однією важливою областю, у якій компілятор Optimum-C вимагає поліпшень, є оптимізація циклів. Компілятор не намагається виконувати винесення інваріантного коду і видалення змінних індукції циклу. Тест виконання показав, що компілятор Datalight дуже ефективно керує введенням/висновком getc/putc, а інші тести виконуються в прийнятний час.
Lattice Inc
Компілятор, що має велику історію, Lattice MS-DOS C послідовно удосконалювався з кожною новою версією. Він відомий як генератор стабільного, передбачуваного коду і виконує помірну оптимізацію. Lattice С виконує зниження потужності, стиск ланцюжка переходів і видалення загальних підвиразів. Він не видаляє присвоювання, що дублюються після тесту вбудованих функцій і зайві присвоювання у функції dead-code. Lattice C не виконує оптимізацію циклів.
Manx Software Systems Inc
Компілятор Aztec C86 згенерував чудовий код з досить гарним рівнем оптимізації. Крім згортки констант і алгебраїчних спрощень, Aztec C86 виконав зниження потужності і видалення загальних підвиразів. Однак, він не виконав видалення зайвих присвоювань і не видаляв недосяжний код. Aztec C86 згенерував код для недосяжного оператора printf разом з безумовним переходом через нього. Оскільки будь-яка програма на Сі має значну кількість викликів функцій, заголовок кожного виклику необхідно мінімізувати. Aztec C86 використовує незвичайний, але ефективний підхід до рішення цієї проблеми. На виході компілятора виходить текст у мові асемблера, що обробляється окремим асемблером. Компілятор вставляє в текст директиви умовного асемблювання навколо коду, що встановлює стековий фрейм і зберігає регістри. Після генерації коду функції, компілятор визначає символи для керування установкою стекового фрейму і збереження тільки тих регістрів, що використовуються у функції. Aztec C86 не зміг вирішити задачу перетворення ланцюжка переходів в один перехід до кінцевої мети. Він також не виконував оптимізацію циклів.
Metaware Inc
High C виробляє чудовий код із середнім рівнем оптимізації. Компілятор виконує всі базові види оптимізації, включаючи згортку констант і алгебраїчні спрощення, видалення зайвих операцій завантаження регістрів, зниження потужності і видалення загальних підвиразів. Компілятор Metaware видаляє недосяжний код, але не видаляє зайві присвоювання. High C розумно використовує машинно-залежні інструкції. Компілятор удосконалить завантаження констант із крапкою, що плаває, використовуючи команду копіювання рядків MOVS процесорів 80x86 для запису значень із крапкою, що плаває, обчислених під час компіляції. Він також генерує інструкцію LEAVE процесорів 80x86 для епілогу функцій, але встановлює адресацію стекового фрейму в пролозі функції за допомогою окремих інструкцій, а не використовуючи більш тривалу інструкцію ENTER. Компілятор High C не виконує винесення інваріантного коду, важливий метод оптимізації циклів. Він також не зміг застосувати успішне видалення змінних індукції циклів. Вбудовані функції підтримуються для декількох цілочисленних і строкових операцій, таких як strlen.
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-програми або наприкінці програми, якщо дозволяє розмір, або ж наприкінці пам'яті.
... кодами сканування клавіатури (scan-коды). Код віджимання є двобайтовим: перший байт рівний F0h, а другий байт збігається з кодом натиснення. Є три рівні програмування підсистеми клавіатури: 1) на фізичному рівні (програмування портів 60h і 64h контроллера клавіатури); 2) за допомогою BIOS ( INT 09h, INT 16h ); 3) за допомогою переривання DOS ( INT 21h ). Для виконання введення даних з клаві ...
... обміну даними з ПЭВМ у процесі виконання програми користувача; 11. Вкажіть типи буферних схем, використаних в УУМС-2. Їх призначення та особливості роботи. 12. Дайте визначення адресного простору мікропроцесорної системи та розпишіть його розподіл в УУМС-2. Адресний простір УУМС складається з областей, состав яких показаний у табл.2. Варто звернути увагу, що внутрішні адресні області ...
... Сван Том. – К.: Диалектика, 1997. – 480с., ил. 7. Секреты Delphi 2: Пер. с англ./Рэй Лишнер. – К.: НИПФ «ДиаСофтЛтд.», 1996. – 800 с. ДОДАТОК ТЕКСТ ПРОГРАМИ “ВІЗУАЛЬНИЙ ОБЛІК ВХІДНИХ ДАНИХ ІНТЕРФЕЙСУ RS-232” Текст основної програми program Project1; uses Forms, MainForm in 'MainForm.pas' {Form1 Головна форма}, GraphicDiagram in 'GraphicDiagram.pas', Unit3 in 'Unit3.pas' ...
... CF (a+b+CF), і розміщує результат замість першого операнда. Обмеження на операнді такі ж, як і в команді ADD. Установлюються прапорці AF, CF, OF, FF, SF, ZF. Ця команда використовується для програмування арифметичних операцій над довгими цілими числами. ІNC a - Збільшення на 1. Команда додає 1 до значення операнда а. Операнд може знаходитися в пам'яті або в регістрі. Установлюються прапорці AF, ...
0 комментариев