Как двоичные файлы запускаются на разных машинах?

Как двоичные файлы запускаются на разных машинах?

Я всегда задавался вопросом, как на самом деле работают исполняемые двоичные файлы. Компиляция всегда обозначается как

берем исходный код и переводим его на машинный язык

Но что это на самом деле означает? А именно:

  1. Могу ли я переместить двоичный файл с компьютера A на компьютер B и ожидать, что он будет работать? (предполагая, что я также перенесу соответствующие библиотеки)
  2. Каждый ли исполняемый двоичный файл предназначен для работы с определенным процессором?
  3. Какая информация содержится внутри исполняемого двоичного файла?
  4. Как получается, что исполняемые файлы в Windows можно запустить в любой версии Windows? (Другая история, если они работают)
  5. Почему я не могу запустить исполняемый файл Linux на Windows? Это связано с ядром (а не с процессором)?

Имейте в виду, что мои познания в процессорах и компиляторах ограничены, а в ассемблере — отсутствуют.

решение1

  1. Не обязательно. Если он создан для переносимости и платформы совместимы, то да (например, 64-битные версии Windows могут выполнять 32-битные и 64-битные исполняемые файлы Windows, но уже не 16-битные).
  2. Не обязательно. Они созданы для определенного набора инструкций. Поскольку это обычно расширения и есть обратная совместимость, вы можете запустить старые файлы на новых процессорах, но не обязательно наоборот. Например, программа, скомпилированная для Windows 95, вероятно, все еще будет работать на современном оборудовании, но вы не сможете запустить программу, скомпилированную для современного оборудования, на старой машине с Windows 95. Однако, если две машины выполняют совершенно разные инструкции, исполняемые файлы не будут совместимы (например, Intel против ARM).
  3. Это зависит от платформы, существует множество форматов с разными заголовками и т. д., но по сути всегда есть какой-то заголовок, работающий как индекс, сообщающий операционной системе, где найти определенные вещи (например, основную точку входа).
  4. На самом деле они этого сделать не могут (см. пункт 2 выше).
  5. Прежде всего, Windows и Linux используют разные форматы для своих исполняемых файлов. Но даже тогда есть различия, например, вся среда и предоставляемые API/библиотеки платформы. Например, исполняемый файл Linux обычно пытается взаимодействовать с оконным менеджером, таким как X11, в то время как программа Windows пытается вызвать API Windows. Однако есть способы заставить такие вещи работать. Старые версии Windows (NT?) на самом деле имели расширения POSIX, поэтому вы могли запускать ограниченный набор программ Linux, насколько мне известно, хотя я никогда не пробовал этого и не присматривался. С другой стороны, для Linux есть такие инструменты, как Wine, которые пытаются эмулировать среду Windows, предоставляя файлы API, преобразования путей и т. д. Это не полная эмуляция (как при использовании виртуальной машины).

решение2

  1. Только при строго контролируемых обстоятельствах: оба компьютера должны иметь совместимый процессор и операционную систему.

  2. Не конкретный процессор, а набор совместимых процессоров. Например, файл, скомпилированный для совместимости с x86 и без расширений, будет работать на каждом процессоре Intel или AMD x86 или x64, при условии совместимости ОС.

  3. Прежде всего, машинный код с этапа компиляции. В дополнение к этому, несколько других так называемых "разделов" будут иметь, например, ресурсы (когда-нибудь задумывались, почему исполняемый файл имеет специальную иконку в Windows, даже если он не запущен, а просто отображается в проводнике), описание двоичной совместимости и многое другое.

  4. Это побочный эффект 1.: Всякий раз, когда ОС обеспечивает совместимость с исполняемым форматом, он может быть запущен. Современные версии Windows обеспечивают ряд совместимости: DOS, Win16, Win32, Win64, dotnet являются наиболее важными.

  5. ОС предоставляет исполняемому файлу среду, которая необходима для выполнения. Эти среды сильно различаются в Linux и Windows. Это означает, что вы не можете напрямую запускать исполняемые файлы из одной системы в другой. Существуют проекты, направленные на преодоление этого разрыва: проект WINE направлен на то, чтобы разрешить запуск исполняемых файлов Windows в Linux (и других ОС), в то время как проект Cygwin направлен на то, чтобы сделать возможным запуск программного обеспечения Linux в Windows. Cygwin не нацелен на двоичную совместимость, а на то, чтобы разрешить перекомпиляцию немодифицированного исходного кода.

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

Связанный контент