根据我对计算机内部原理的粗略理解,如果为特定的指令集架构编译 C 程序,则生成的可执行文件对于任何操作系统都是相同的,系统调用除外。
另一方面,不同指令集架构的可执行文件完全不同。
那么,为什么当您想要下载互联网程序时,您通常会根据操作系统而不是指令集架构做出选择?
此外,由于指令集架构如此之多,我真的无法想象安装程序是什么样子。例如,如果安装程序支持 20 种不同的架构,那么 95% 的数据是否会在安装过程中被丢弃?
答案1
.deb 等安装文件是否包含针对每种受支持架构的机器指令?
不,.deb 软件包(以及几乎所有 Linux 打包系统的软件包)仅针对一种特定架构构建。通常该架构甚至会在文件名中注明。
那么,为什么当您想要下载互联网程序时,您通常会根据操作系统而不是指令集架构做出选择?
Windows 主要仅支持 x86(_64) 架构。(大多数开发人员不认为 Alpha AXP 和 Itanium 有相关性,而 ARM 版本的 Windows 根本不允许运行第三方程序。)
OS X 和 iOS 使用“fat 二进制文件”(见下文)。
对于 Linux/BSD,提供可编译的源代码,最终用户(或发行版打包者)根据所需的架构构建它。
(如果软件仅以二进制形式提供怎么办?
好吧,99% 的时间,如果您不是在 x86 上,那么您就完蛋了。)Android 应用程序以 Dalvik 字节码的形式分发;它们在安装过程中被转换成本机代码(如果您有 ART)。
.NET“托管”代码的工作方式相同;.exe 文件包含 CIL 字节码,它恩根可以在安装期间转换为本机代码,或者可以在.NET 运行时直接运行。
例如,如果安装程序支持 20 种不同的架构,那么 95% 的数据是否会在安装过程中被丢弃?
取决于安装方法。(我们假设该程序是作为本机二进制文件构建的,而不是 Android/.NET/Java 字节码。)
在 Windows 情况下,通常您首先会有几个不同的单一架构安装程序,并且只下载正确的安装程序。
但是,当程序以单张多架构 CD 的形式发布时,安装程序只会复制适合您的架构的文件,而忽略其他所有内容。(毕竟,复制不可用的文件是没有意义的。)
对于 Linux 软件包来说,情况也是一样的——一堆特定于 arch 的 .deb 包,例如。
自从从 PowerPC 转向 Intel 以来,许多 OS X 程序都以“胖二进制文件”的形式构建,即单个可执行文件包含两种架构的代码,当您“安装”它时,所有内容都会被准确复制。(所以,是的,这些程序的大小往往是其应有大小的两倍。)
不过,我听说 iOS App Store 已经转为仅接受 LLVM 位码并自动将其编译为适用于所有架构的单独版本。