【问题标题】:Why are executables in machine code operating system dependent?为什么机器代码操作系统中的可执行文件依赖于?
【发布时间】:2011-07-03 01:52:56
【问题描述】:

在 Windows 中,当我编译一个简单的“C”程序时,我得到了最终的可执行机器代码 .exe 。 在 unix 中使用 gcc 相同的东西会产生一个 .out 机器代码文件。

这些有什么区别?

我的基本问题是,.exe.out 是机器代码,为什么它们依赖于操作系统?

如在 Unix 中,我不能直接执行 .exe,而在 Windows 中,我不能执行 Unix 的 .out。为什么会这样?

【问题讨论】:

  • 实际上,Unix 系统并不像 Windows 那样严格地使用文件扩展名。您可以在 Unix 中随意命名文件。 gcc 倾向于生成名为“a.out”的文件,除非您指定不同的输出文件名。

标签: c operating-system


【解决方案1】:

在 unix 环境中,任何设置了 +x 位的文件都被视为可执行文件。请记住,即使是非二进制文件也可以是可执行的(shell 脚本、批处理文件等)。 Windows 依赖于文件扩展名的概念,在 Unix 上我们只设置chmod +x filename

您总是可以使用 -o file 标志来强制 gcc 生成您喜欢的任何文件名。

【讨论】:

    【解决方案2】:

    这一切都与程序的加载方式有关。

    Windows 和 Linux 对于它们希望程序如何定义自身具有不同的格式。

    在 Linux 中,通常使用 ELF 格式。对于 Windows,它是 PE

    这些格式定义了执行机器指令所需的有关程序的不同数据。

    另外,操作系统接口不同,需要使用不同的库,进行不同的系统调用。

    对于一个简单的程序,您通常可以在另一个操作系统上重新编译以使其在两个操作系统上都运行,但您将无法在两个操作系统上使用单个文件。

    【讨论】:

    • 我打算写一个完整的答案,但这就是它会添加到你的答案中的全部内容,这是首先完成的。 *尼克斯:ELF。窗口:PE
    • 感谢您的链接,为了完整起见,我将它们添加到答案中。
    • 重要的一点是可执行文件通常只是原始机器代码 - 它们是与许多其他数据打包在一起的机器代码,这些数据告诉操作系统如何加载并运行代码。
    • 两个文件都不使用?实际上,在 Linux 上,您可以设置对自定义二进制格式 (Google binfmt_misc) 的支持,这样您就可以透明地将 PE 可执行文件传递给 Wine :-)
    【解决方案3】:

    操作系统抽象出对底层硬件的访问,并通过系统调用将其提供给程序员。在 Windows 中,这些是通过 Windows API 完成的(通常由使编程更容易的库进一步抽象,如 MFC 等)。在 UNIX 中,这通常是通过中断来完成的,系统的 C 库通过遵循 POSIX api(通常带有一些与系统相关的添加)使中断变得更容易一些。

    例如,在 Linux 上,系统调用是通过 int 0x80 进行的,其中几个寄存器被加载了函数的参数,而 C 库通过允许您调用来使这更容易,例如read,带有预期的参数( int fd, void *buf, size_t count )。这被翻译成一个中断调用,内核对其进行响应。

    这两种向操作系统发出请求的方式是不兼容的,因此您(通常)不能在 UNIX 系统上运行 Windows 可执行文件,反之亦然,除非使用一些充当翻译层的附加系统,例如WINE、VMWare 等(尽管这两者的工作方式非常不同)。

    (顺便说一句,a.out 没有说明可执行文件的内容;它是在 UNIX 系统上编译的可执行文件的传统文件名,是“汇编器输出”的缩写。GCC 允许交叉编译,因此您甚至可以编译Win32兼容的.EXE文件。你可以使用gcc的-o标志来指定输出文件名,这表明它与输出文件的实际格式无关。)

    【讨论】:

    • Windows API 最终确实会使用陷阱到主管指令intsyscallsysenter 之一进行系统调用(从 ntdll,如果内存可用),就像 Unix . (调用门将是 x86 上的另一种可能性,但 IIRC 不再使用它们,因为它们更慢。)当然,陷阱编号、系统调用编号和系统调用语义完全不同。
    • 谢谢,我怀疑最终会需要这种东西,但我早就离开了平台。
    猜你喜欢
    • 2012-08-02
    • 2017-04-30
    • 1970-01-01
    • 2018-08-31
    • 2019-03-18
    • 2013-08-31
    • 2018-02-13
    • 1970-01-01
    • 2019-10-29
    相关资源
    最近更新 更多