Почему исполняемые файлы в операционной системе машинного кода зависят?
в 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 производить любое имя файла, которое вам нравится.