据我所知,每个CPU /架构都有自己的指令集,因此为特定CPU编写的程序(二进制)无法在另一个CPU上运行。但我真正理解的是为什么一个可执行文件(例如.exe这样的二进制文件)无法在Linux上运行,但即使在同一台机器上也可以在Windows上运行。
这是一个基本问题,我期待的答案是.exe和其他二进制格式可能不是原始机器指令,但它们包含一些依赖于操作系统的数据。如果这是真的,那么这个OS依赖的数据是什么样的?作为一个例子,.exe文件的格式是什么,以及它与Linux可执行文件之间的区别?
是否有消息来源我可以获得有关此内容的简短详细信息?
答案 0 :(得分:20)
为了做有意义的事情,应用程序需要与操作系统连接。由于系统调用和用户空间基础架构在Windows和Unix / Linux上看起来与基本不同,因此对可执行程序使用不同格式是最小的麻烦。 程序逻辑需要更改。
(你可能会认为,如果你的程序完全依赖于标准化的组件,例如C运行时库,那就毫无意义。这在理论上是正确的 - 但对于大多数应用程序来说无关紧要,因为它们被迫使用依赖于操作系统的东西)。
Windows PE (EXE,DLL,..)文件和 Linux ELF 二进制文件之间的其他差异与不同的图像加载器和两个操作系统的一些设计特征有关。例如,在Linux上,单独的程序用于解析外部库导入,而此功能是在Windows上内置的。另一个例子:Linux共享库的功能与Windows上的DLL不同。更不用说两种格式都经过优化,以使相应的OS内核能够尽快加载程序。
像Wine这样的模拟器试图填补空白(并且实际证明最大的问题不是二进制格式,而是操作系统界面!)。
答案 1 :(得分:5)
.exe和其他二进制格式[绝对]不是原始机器指令,但它们包含一些依赖于操作系统的数据。
这个OS依赖的数据是什么样的?作为一个例子,.exe文件的格式是什么,以及它与Linux可执行文件之间的区别?
好吧,我猜Google完全失败了。 Windows文档很好地定义了.EXE格式。
http://support.microsoft.com/kb/65122
Linux ld
应用程序在“exec”之前将可执行文件加载到内存中。您可以阅读ld
格式甚至是着名的a.out
文件。
答案 2 :(得分:5)
除了必须由系统加载程序识别的可执行格式(即将可执行文件带入内存的操作系统的那部分)之外,真正的问题是操作系统的接口。您可以将操作系统视为一种API,它提供了执行特定操作时必须调用的入口点,例如,将字符写入控制台。
这些细节通常或多或少地隐藏在最终用户之外,因此您可以使用更高级语言中的相同源代码将字符编写到屏幕上。但通常情况会更加不同,例如Windowing环境。并非所有高级语言都提供了一个窗口层,即使在这些差异上也是如此。
答案 3 :(得分:3)
一个非常幼稚的回答:
答案 4 :(得分:3)
我不能对* nix做太多评论但是,二进制文件的代码部分通常很乐意在任一环境中运行,但是操作系统对二进制文件提出了某些要求。在Windows中,您应该阅读PE Headers。
第二部分仅仅是开发人员,很多时候代码部分将引用特定于操作系统的库 - 这就是为什么在编译成二进制文件之前可以同时拥有可移植和非可移植C ++代码的原因。
答案 5 :(得分:1)
程序需要知道如何调用操作系统服务。如何完成这取决于操作系统:一些使用中断,一些使用x86 lcall
指令,一些(特别是Windows)具有区分共享库,而不记录如何直接调用服务。旧的680x0 Mac和其他一些680x0操作系统使用保留指令集区域并捕获由此产生的“无效CPU操作码”异常。此外,即使机制相同,系统调用的顺序和参数格式也会在操作系统之间有所不同(有时是同一操作系统的不同版本;请参阅Linux内核中的stat()
以获取接口的示例已多次改变)。
有一些处理其他操作系统惯例的能力:FreeBSD有“linuxulator”处理特定于Linux的内核接口,NetBSD同样具有用于其他操作系统调用格式的仿真器使用相同硬件的系统(例如,MIPS上的Ultrix或Alpha上的OSF / 1),Linux曾经使用iBCS2来处理UnixWare / SCO Unix内核接口,Wine为PE风格的Windows可执行文件提供替换共享库和二进制加载器。 (我不记得Wine是否也支持OS / 2风格的LX .exe
;它可能确实处理原始格式.exe
;然后是.com
这是一个原始内存转储打了一个标题。)即便如此,总会有一些格式使用不同的约定,有时候约定足够相似,需要提示操作系统如何处理它。 (例如,请参阅FreeBSD上的bless
。)