二进制文件如何在不同的机器上运行?

Pit*_*kos 6 windows linux cpu compile binary-files

我一直想知道可执行二进制文件实际上是如何工作的。编译总是声明为

获取源代码并将其翻译为机器语言

但这到底意味着什么呢?即:

  1. 我可以将二进制文件从计算机 A 移动到计算机 B 并期望它正常工作吗?(假设我也移动了适当的库)
  2. 每个可执行二进制文件都适合与特定处理器一起使用吗?
  3. 可执行二进制文件中包含哪些类型的信息?
  4. 为什么Windows上的可执行文件可以在任何Windows版本上启动?(如果有效的话那就是另一个故事了)
  5. 为什么我无法在 Windows 上运行 Linux 可执行文件?它与内核有关(所以与处理器无关)吗?

请注意,我对处理器和编译器的了解有限,并且对汇编一无所知。

Mar*_*rio 3

  1. 不必要。如果它是为了可移植性而构建的并且平台兼容,那么可以(例如,64 位版本的 Windows 能够执行 32 位和 64 位 Windows 可执行文件,但不再是 16 位版本)。
  2. 不必要。它们是为特定指令集而设计的。由于这些通常是扩展并且具有向后兼容性,因此您可能会在较新的处理器上运行较旧的文件,但不一定是相反。例如,为 Windows 95 编译的程序可能仍然可以在当今的硬件上运行,但您无法在旧的 Windows 95 计算机上运行为当今的硬件编译的程序。但是,如果两台机器运行完全不同的指令,则可执行文件将不兼容(例如 Intel 与 ARM)。
  3. 这是依赖于平台的,有多种格式具有不同的标头和内容,但基本上总是有某种标头作为索引,告诉操作系统在哪里可以找到特定的东西(例如主入口点)。
  4. 他们实际上不能(参见上面的#2)。
  5. 首先,Windows 和 Linux 的可执行文件使用不同的格式。但即便如此,还是存在差异,例如整个环境和提供的平台 API/库。例如,Linux 可执行文件通常会尝试与 X11 等窗口管理器通信,而 Windows 程序会尝试调用 Windows API。然而,有一些方法可以让这些事情发挥作用。旧版本的 Windows(NT?)实际上具有 POSIX 扩展,因此据我所知,您可以运行一组有限的 Linux 程序,尽管我从未真正尝试过或仔细研究过。另一方面,对于 Linux,有诸如 Wine 之类的工具,它将尝试模拟 Windows 环境,提供 API 文件、路径转换等。这不是完整的模拟(就像使用虚拟机一样)。