参考答案:为什么不同的系统编译出来的同一个可执行二进制文件不兼容?
主要原因是格式不同和API不同,前者更重要。
可执行的二进制文件不仅包含机器指令,还包含各种数据和程序运行资源,机器指令只是其中的一部分。
当一个可执行文件要执行时,操作系统需要为其分配资源。 这些资源包括:内存空间(物理的和虚拟的)、进程、线程资源等。可执行文件的机器指令一般放在Code段(汇编语言中称为文本段),其他资源可能放在数据段和其他部分。 这里的“”()可以粗略地理解为一个内存范围。 操作系统(/Linux)需要知道这个可执行文件需要多少内存,有多少段,以及加载到哪些内存地址。 可执行文件需要告诉操作系统需要什么来准备可执行文件以使其运行。
在执行可执行文件之前,操作系统必须做一些准备工作。 由于不同的操作系统需要的准备工作不同,因此可执行文件的格式也不完全相同。 网上大多数可执行文件都是PE格式,Linux中大多数可执行文件都是ELF格式。 不同的格式导致不同的可执行文件,不能直接跨平台使用。 这是原因之一。
当然,我在网上看到专家用不同的格式解决了一些问题,但是跨平台运行还有一个障碍需要解决,那就是操作系统API的不同。 可执行文件执行的大部分操作(如文件操作、输入输出、内存分配与释放、任务调度等)都需要与操作系统交互来完成,而不同的操作系统使用这些操作的方式完全不同。 ,所以这个障碍比较难克服。 这是第二个原因。
如果能解决以上两个原因,那么理论上有些可执行文件可以跨Linux和Linux运行在x86平台上,因为Intel和AMD CPU中的主要硬件指令(机器指令)是相同的,也就是说像0101这样的二进制数是相同的。 但如果换成ARM平台,更大的麻烦就会是硬件指令也不同,所以就无能为力了。
是否可以有一个跨平台运行的可执行文件? 理论上是存在的。 过去有一些方法,但是有很多限制。 例如,过去支持COM格式的文件。 该文件没有文件头,大小不能超过64K,只能在16位环境(真实或虚拟)中运行,并且是真正的裸二进制文件。 Linux中的一些BIN文件恰好是裸二进制文件(有些BIN文件没有ELF头,但并非所有BIN都是这样)。 经过一些配置,BIN文件也可以在Linux上运行。 因此,一些设计良好的COM/BIN文件在极其限制的情况下可以跨平台运行,但它们可能只能进行计算而不能输出,而且大小只有64K。 而如果想做稍微复杂一点的操作,就需要两套机器码来实现。 此外,遗憾的是,64 位环境不再支持 COM 文件。
----------------------------------------------------
最后我想补充一点,如果把所有的驱动、应用库等都打包在一起,然后突破格式的限制,那不就是一个操作系统了吗? 和安装双系统没有什么区别。