Почему исполняемые файлы в операционной системе машинного кода зависят?

в windows, когда я компилирую простую программу "C", я получаю окончательный исполняемый машинный код .exe . То же самое, что использование gcc в unix дает .out файл машинного кода.

в чем разница между ними?

мой основной вопрос, .exe и .out будучи машинными кодами, почему они зависят от операционной системы?

как в Unix я не могу выполнить .exe прямо и в Windows, я не могу выполнить .out Unix. Почему это так?

3 ответов


все это связано с тем, как программа загружается.

Windows и Linux имеют разные форматы для того, как они хотят, чтобы программа определяла себя.

в Linux эльф формат обычно используется. Для Windows это PE.

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

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

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


операционная система абстрагирует доступ к аппаратной, и делает его доступным для программистов через системные вызовы. В Windows это делается через API Windows (который обычно дополнительно абстрагируется библиотеками, которые упрощают программирование, например MFC и т. д.). В UNIX это часто делается через прерывания, которые библиотека c системы делает немного проще, следуя api POSIX (часто с несколькими системно-зависимыми дополнениями).

например, в Linux, системные вызовы выполняются через int 0x80, с несколькими регистрами, загружаемыми аргументами функции, и библиотека C упрощает это, позволяя вам вызывать, например read, с ожидаемыми аргументами ( int fd, void *buf, size_t count ). Это преобразуется в вызов прерывания, на которые ядро реагирует.

эти два способа выполнения запросов к операционной системе несовместимы, и поэтому вы (как правило) не можете запускать исполняемый файл Windows в системах UNIX, и наоборот, без использования какой-либо дополнительной системы, которая действует как слой перевода, например WINE, VMWare и т. д. (хотя то, как эти два работают, очень отличается).

(кстати, a.out ничего не говорит о содержимом исполняемого файла; это традиционное имя файла, данное исполняемым файлам, скомпилированным в системах UNIX, и является коротким для "вывода ассемблера". GCC позволяет перекрестную компиляцию, так что вы можете даже компилировать Win32-совместимый .EXE файлы с ним. Вы можете использовать -o флаг для gcc, чтобы указать выходное имя файла, которое показывает, что оно не имеет отношения к фактическому формату выводимого файла.)


в среде unix любой файл, имеющий бит +x, считается исполняемым. Помните, что даже не двоичные файлы могут быть исполняемыми (сценарии оболочки, пакетные файлы и т. д...). Windows опирается на концепцию расширения файла, на Unix мы просто установили chmod +x filename.

вы всегда можете использовать -o file флаг, чтобы заставить gcc производить любое имя файла, которое вам нравится.