Чому виконувані файли залежать від ОС, але не від процесора?


16

Якщо я напишу програму C і компілюю її у .exeфайл, то цей .exeфайл містить впорядковані машинні інструкції до центрального процесора. (Я думаю).

Якщо так, то як мені можна запустити скомпільований файл на будь-якому комп’ютері, на якому працює сучасна версія Windows? Кожна сім'я процесорів має різний набір інструкцій. То як же будь-який комп'ютер, на якому працює відповідна ОС, може зрозуміти інструкції в моєму .exeфайлі, незалежно від фізичного процесора?

Крім того, часто на веб-сайтах, що перебувають на сторінці "завантаження" якогось додатка, у вас є завантаження для Windows, для Linux та Mac (часто це два завантаження для кожної ОС, для 86 та 64-бітних комп'ютерів). Чому не існує набагато більше завантажень для кожної сім'ї процесорів?


4
Процесорні процесори мають стандартні види, такі як x86, 64b тощо. Виконані файли DO залежать від процесора. Ви не можете запустити свого exe, про якого ви згадали, на якомусь спеціальному процесорі, наприклад, RISC, є також безліч спеціальних процесорів
InformedA

ОС складаються з виконуваних файлів, і вони залежать від процесора, а не від ОС, оскільки вони є ОС.
Tulains Córdova

Через зворотну сумісність.
МіКЛ

2
часто два завантаження для кожної ОС, для 86 та 64-бітних комп'ютерів : я трактую це як залежність виконуваних файлів від процесорів.
mouviciel

Відповіді:


37

Виконані файли дійсно залежать і від ОС, і від процесора:

  • Набір інструкцій: Двійкові інструкції у виконуваному файлі декодуються процесором відповідно до деякого набору інструкцій. Більшість процесорів споживачів підтримують набори інструкцій x86 ("32 біт") та / або AMD64 ("64 біт"). Програма може бути складена для будь-якого з цих наборів інструкцій, але не для обох. Існують розширення до цих наборів інструкцій; підтримку для них можна запитувати під час виконання. Наприклад, такі розширення пропонують підтримку SIMD. Оптимізація компіляторів може спробувати скористатися цими розширеннями, якщо вони є, але зазвичай також пропонують шлях коду, який працює без будь-яких розширень.

  • Бінарний формат: виконуваний файл повинен відповідати певному бінарному формату, що дозволяє операційній системі правильно завантажувати, ініціалізувати та запускати програму. В основному Windows використовує формат Portable Executable, тоді як Linux використовує ELF.

  • Системні API: Програма може використовувати бібліотеки, які повинні бути присутніми у виконуючій системі. Якщо програма використовує функції з API API, вона не може бути запущена в Linux. У світі Unix API центральної операційної системи були стандартизовані на POSIX: програма, що використовує лише функції POSIX, зможе запускатись у будь-якій відповідній системі Unix, наприклад, Mac OS X та Solaris.

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

Однак існують способи досягнення більшої сумісності:

  • Системи, що працюють на наборі інструкцій AMD64, зазвичай також запускають виконувані файли x86. Бінарний формат вказує, у якому режимі працювати. Обробка 32-бітових та 64-бітних програм вимагає додаткових зусиль операційної системи.

  • Деякі бінарні формати дозволяють файлу містити кілька версій програми, складених для різних наборів інструкцій. Такі «жирні бінарні файли» заохочували Apple, переходячи від архітектури PowerPC до x86.

  • Деякі програми складаються не до машинного коду, а до деякого проміжного представлення. Потім він перекладається на ходу до фактичних інструкцій, або може бути інтерпретований. Це робить програму незалежною від конкретної архітектури. Така стратегія була використана в p-System UCSD.

  • Одна операційна система може підтримувати кілька бінарних форматів. Windows є досить сумісним назад і досі підтримує формати з епохи DOS. У Linux Wine дозволяє завантажувати формати Windows.

  • API однієї операційної системи можна повторно доповнити для іншої хост-операційної системи. У Windows, Cygwin та підсистему POSIX можна використовувати для отримання (переважно) середовища, сумісного з POSIX. У Linux Wine поповнює багато API API.

  • Міжплатформні бібліотеки дозволяють програмі бути незалежною від API API. У багатьох мовах програмування є стандартні бібліотеки, які намагаються цього досягти, наприклад, Java та C.

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


10
Слід зазначити, що і java, і .net - приклади використання проміжного формату - проміжні формати сьогодні дуже популярні, а не просто пережиток системи 1970-х років, на якій було запущено 5 1/4 дискети.
jmoreno

@AKoscianski дякую за запропоновані зміни . Однак, я думаю, що дизайн безпеки не є причиною, по якій виконувані файли залежать від ОС, а причина, чому ми в першу чергу розділимо ОС проти користувача. Різні API для такої функціональності захищеної операційної системи вже були розглянуті розділом "Системні API" цієї відповіді.
амон

2

99% сучасних ПК під управлінням Windows мають 64-бітний процесор, який також здатний працювати з 32-бітним програмним забезпеченням. Інший відсоток має 32 бітові процесори. Тож програмне забезпечення, створене для 32-бітних процесорів, працює всюди. Програмне забезпечення, створене для 64-бітних процесорів, працює на кожному ПК, про який піклується автор програмного забезпечення.

MacOS X і iOS підтримують "жирові файли" - те, що ви завантажуєте, може містити версії для різних процесорів. Ніхто більше не створює програми для процесорів PowerPC, але в якийсь момент кілька років тому виконуваний файл міг містити PowerPC, 32-бітну Intel та 64-бітну версію Intel, і потрібна буде виконана. На iOS сьогодні, коли ви завантажуєте додаток, ви отримаєте версію, підходящу для процесора на своєму пристрої. Завантажте на інший пристрій, і ви отримаєте іншу версію. Повністю невидимий для користувача.


-1

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.