【问题标题】:Executing Binary Files执行二进制文件
【发布时间】:2012-02-10 03:45:08
【问题描述】:

我下载了一个使用 GCC 4.4.4 for x86-64 Red Hat Linux 编译的二进制文件(一个 C 程序)。

当我尝试在运行 GCC 4.2.1 的 Mac OS X(运行 Lion 以及 x86-64)上运行它时,它会说:cannot execute binary file,这是否正常?它无法将其检测为二进制文件。

为什么要这样做?我相信 gcc 版本与此无关,因为该文件已经编译。它已经为两台机器都运行的 x86-64 编译。谁能解释一下?

【问题讨论】:

    标签: linux macos unix gcc x86


    【解决方案1】:

    有不同的二进制格式。 Linux 系统使用ELF 表示可执行文件和库,但Mac OS X 使用Mach-O format。 Windows 使用另一个静止图像:PE format

    【讨论】:

      【解决方案2】:

      为特定操作系统编译的二进制文件极不可能在另一个操作系统上运行。要么获取 Mac 的二进制文件,要么获取源代码并自行编译。

      有很多因素会导致问题 - libc 和 libstdc++ 的版本,.so 库的版本可能存在差异 - 操作系统本身的 API 接口不同。甚至是不同的二进制格式(即 VMS 二进制文件不在 AIX 上运行)。

      【讨论】:

      • 两者都不运行 x86-64 吗?从某种意义上说,编译器会将两者都编译为 x86 程序集(在两台机器上都是相同的)。那么这是否意味着汇编程序会将汇编代码转换为每台机器上的不同二进制文件?
      • 实际指令的编译结果可能是相同的,但是假设我们有 Nayefc 操作系统 - 您可能决定您希望首先使用所有全局变量布局可执行文件,然后是函数,然后是硬编码文本字符串,现在我编写了 Adrian OS 我首先想要这些功能,然后是 27680 字节的间隙(因为我喜欢它)然后.. - 你明白了。所以windows EXE不同于Linux exe,可能是Mac exe
      【解决方案3】:

      虽然 Rad Hat Linux 和 Mac OS X 都是“基于 Unix”的,但它们不能运行彼此的二进制文件。就像您不能在 Mac 上运行 Windows 二进制文件一样,反之亦然。

      【讨论】:

        【解决方案4】:

        当您的程序有一个归结为操作系统调用的 printf() 时,编译这种意义上的二进制文件是为了进行操作系统调用。如果编译它的操作系统是 64 位 redhat linux,那么这可能意味着二进制文件将在 redhat linux 路径中为共享库查找 redhat linux 名称。这与完全不同的操作系统、Mac OS X 及其系统调用和共享或静态库等完全没有任何关系。这就像从迷你铜桶上取下一个轮子并试图用螺栓固定它上一辆自行车。是的,它曾经是原始金属和橡胶,可以制成自行车轮胎。但是,一旦你制作了二进制文件,汽车轮胎或自行车轮胎,它就是这样。有时你会发现一个模拟器,比如在 posix 系统上模拟 windows 的 wine。或者像 vmware 这样的虚拟机,通过虚拟化整台计算机,您可以在另一个操作系统之上运行完全不同的操作系统。

        您通常不能期望使用任何旧的 C 程序并让它在任何具有 gcc 编译器的操作系统上编译和运行,这也是事实。是的,您可以学习编写可移植的 c 程序,但您必须谨慎使用所有目标平台都支持的库。因此,即使将程序的源代码带到 mac 并编译它也不一定能正常工作。

        【讨论】:

        • 但不是都运行 x86-64 吗?从某种意义上说,编译器会将两者都编译为 x86 程序集(在两台机器上都是相同的)。那么这是否意味着汇编程序会将汇编代码转换为每台机器上的不同二进制文件?
        • 汇编器和编译器无关,重要的是该平台的系统库,linux和macos是不同的平台,就像必须制作橡胶轮胎和金属轮一样为了适应不同尺寸的车辆,轮胎和车轮的侧面可以是相同的品牌,相同的机械师可以安装它们,但这并不意味着一个轮胎适合所有人。如果操作系统相同,就不会有windows和linux和macos等。
        • 纯粹意义上的汇编器和编译器和链接器只需要知道它是一个x86-64。例如,您使用 printf 制作了一个 hello world 程序。甚至 C 库的大部分内容都是一致的并且可以跨平台移植,但是您的程序所在的 C 库层有另一面,另一面是 C 库与操​​作系统的接口,这也是与某些人不同的地方在 C 库端或操作系统端或两者都必须对其进行自定义,以对最终不可移植的特定操作系统进行系统调用。
        • 创建一些非常简单的东西,一个 printf 很复杂但可能足够简单,也许只是一个带有单个 putchar 或 putc 的程序,在两个平台上编译它,静态链接而不是动态链接。拆开两者并进行比较。
        猜你喜欢
        • 2013-12-02
        • 2013-08-04
        • 1970-01-01
        • 1970-01-01
        • 2014-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多