Разница между программами, скомпилированными для разных ОС

8

С точки зрения скомпилированного кода, в чем разница между программой, скомпилированной для одной ОС против другой (например, Linux против Windows). Разве программа не запускается непосредственно на процессоре? Или это потому, что программа должна ссылаться на конкретные библиотеки ОС?

AGZ
источник

Ответы:

6

Обычные скомпилированные программы «запускаются напрямую» на процессоре, но программа не запускается в вакууме:

  1. Многие программы используют внешние динамически загружаемые библиотеки ( DLLsили .soбиблиотеки). Способ их связывания зависит от компилятора / компоновщика, и каждая ОС имеет свои стандарты. Однако существуют также «статически связанные» программы, которые предоставляют весь собственный код.

  2. Современная ОС не дает полного контроля над работающей программой. Программы полагаются на «системные вызовы» для ввода-вывода, доступа к оборудованию и таким вещам, как сигналы и переход в спящий режим. Доступные сервисы и интерфейс определяются ОС. ОС также контролирует, какие части системы (память, регистры, прерывания) программе разрешено использовать.

  3. Программа с графическим интерфейсом также должна работать в графической среде пользователя, чтобы рисовать себя на экране. Но вы, наверное, уже думали об этом.

По этим причинам независимые от ОС приложения должны полагаться на какую-то «виртуальную машину», подобную той, которая предоставляется средой выполнения Java. Важно отметить, что виртуальная машина предоставляет стандартный интерфейс для ресурсов ОС (ввод-вывод, сигналы и т. Д.). Конечно, Java или Python также интерпретируют «байт-код» вместо того, чтобы иметь дело с особенностями набора команд Intel; но это другая история.

Alexis
источник
Кроме того, разные ОС имеют разные стандарты для компоновки стека, практики выравнивания памяти и т. Д., Поэтому даже чисто числовой / вычислительный код может отличаться от одной ОС к другой.
Даниэль Р Хикс
Могут ли эти различия помешать выполнению статически скомпилированного кода? Не знал, что ..
Алексис
Вероятно, это просто теоретическая проблема, поскольку какая-то другая несовместимость поможет вам в первую очередь. Но операционные системы часто имеют ожидания относительно того, как выровнены кадры стека, где хранятся регистры и т. Д. Они могут варьироваться от одной ОС к другой для той же аппаратной архитектуры. Теоретически вы можете запускать «чужой» код, который является чисто вычислительным, но вы никогда не сможете его запустить и никогда не сможете завершить его чисто.
Даниэль Р Хикс
5

Разные ОС также имеют разную функциональность. В Windows есть порты завершения ввода / вывода, в Linux нет. У FreeBSD есть kqueue, у Linux нет. У Linux есть фьютексы, у Windows нет. У них также есть разные способы сделать одно и то же - какие параметры вы передаете, чтобы открыть файл? В каком порядке они идут? Как конкретно вы вызываете функцию операционной системы "открыть файл"?

Дэвид Шварц
источник
Хорошо, это имеет смысл, но в целом программа загружается в память и запускается на процессоре, или ОС "контролирует" программу
agz
1
@agovizer: оба. Они не являются взаимоисключающими. Как правило, ОС устанавливает контролируемую среду и организует аппаратное прерывание программы за определенное время, а затем передает ядро ​​программе. Но как только программа выполнит любое количество условий (например, сбой страницы, операция ввода-вывода и т. П.), ОС снова вступит во владение.
Дэвид Шварц
5

Как правило, программы несовместимы из-за различий в их двоичном интерфейсе приложения (ABI) .

Разве программа не запускается прямо на процессоре?

НЕТ ! Это задача операционной системы - предотвращать запуск приложений «непосредственно» на процессоре. Как правило, на самом низком уровне (то есть на том, на котором построен API-интерфейс ОС) приложение взаимодействует с ядром операционной системы .

Это потому, что сама скомпилированная программа должна ссылаться на определенные библиотеки ОС?

Да . Многие библиотеки ОС написаны для облегчения взаимодействия с самой операционной системой, но столько же написано для кроссплатформенности. Они скрывают низкоуровневый интерфейс ОС от разработчика и предполагают, что скомпилированная версия для этой ОС будет доступна во время выполнения (см. Ниже).

Хотя библиотеки могут быть написаны в кросс-платформенных образом, при компиляции они не могут работать кросс-платформенный. Их по-прежнему необходимо перекомпилировать для конкретной целевой операционной системы, чтобы снова использовать конкретные базовые компоненты операционной системы (ядра).

В чем разница между скомпилированной программой для одной ОС против другой?

Наконец, сами исполняемые файлы часто содержат очень специфичные двоичные заголовки загрузки и т. Д. (Например, формат исполняемого файла PE [.exe, .dll и т. Д.] Для Windows или ELF для Linux [нет, .o, .so , так далее...]). Они также могут включать в себя код для загрузки скомпилированных специфичных для ОС двоичных файлов для конкретной библиотеки программного обеспечения.


Наконец, с точки зрения программиста: соглашение о вызовах . Скомпилированный код передает переменные функциям заданным образом (т.е. через регистры или в стеке) в очень определенном порядке. Даже в этом случае необходимо также договориться о том, кто отвечает за «очистку» вызовов функций (вызывающий или вызываемый?). Хотя существует несколько стандартных и широко используемых соглашений о вызовах x86 , некоторые из них могут не поддерживаться определенными операционными системами (это является частью ABI).

Прорыв, достижение, открытие
источник