【问题标题】:Am I coding for an OS or the Processor?我是在为操作系统或处理器编码吗?
【发布时间】:2010-11-20 09:45:44
【问题描述】:

据说通过使用 C/C++,人们可以编写“本机”程序——在平台上运行。我对什么被认为是原生感到困惑 - 处理器架构或操作系统版本?

例如:

我有一个 32 位处理器和 Windows 7(32 位),我编译并生成了 .exe 文件。是否保证可以在任何 Windows 7 32 位上运行? (Win 7 32 位在 32/64 位机器上)

编辑1: 我不打算在这里只使用 Windows 操作系统。我的示例也可以扩展到 Linux。例如,在 32 位处理器上运行的 32 位 Linux 操作系统上生成可执行文件(默认为 a.out),然后在 64 位处理器上的 32 位 Linux 上运行它。

编辑2: 感谢您的回复,但我也打算使用标准库和函数 - 没有特定于操作系统的内容。仅由 ANSI 或 ISO C++ 标准指定一次。不引用操作系统特定的窗口系统或其他库。 谢谢

【问题讨论】:

    标签: c++ c executable native


    【解决方案1】:

    两者;那种。

    实际指令在 Windows 和 Linux 之间并没有真正的不同,因为它们是针对单一 CPU 架构 (x86) 编译的。

    但是,二进制文件不仅仅是在裸硬件上运行的代码。例如,它还包含告诉操作系统如何加载可执行文件及其依赖项的信息。二进制文件以特定格式打包。这种格式在不同的操作系统中可能会有所不同。

    除此之外,操作系统还为应用程序提供一些服务(通过系统调用和 API)。操作系统提供的服务以及它们的使用方式因操作系统而异。

    这些原因导致大多数时候原生二进制文件同时依赖于编译它的操作系统和 CPU 架构。


    回答更新的问题:

    C++ 标准对编译目标的性质没有任何要求。它只是在源代码级别指定兼容性要求。因此,如果您坚持使用标准库,您将能够使用相同的源代码在提供符合 C++ 实现的平台上进行编译。该标准没有说明二进制可移植性。正如我上面提到的,操作系统提供的原始系统调用可能会有所不同,标准库的实际实现取决于操作系统提供这些系统调用的方式。

    为了在 Linux 上运行 Windows 二进制文件,您需要使用某种模拟,例如 Wine,它可以理解 Windows 二进制格式并为应用程序模拟 Windows API。

    【讨论】:

    • +1 用于解释为编码和为平台编译的区别。
    • +1 表示“二进制兼容性”。但我指的不是跨平台二进制兼容性——我指的是 Windows 上的 Windows 二进制文件和 Linux 上的 Linux 二进制文件(尽管在不同的架构上,比如 32/64/其他架构上的 32 位操作系统)
    • @user331225:对于两种不同的架构,生成的代码会有所不同。请注意,x86-64 实际上只是对 x86 的扩展,它并不是一个根本不同的架构。这就是为什么 32 位 x86 应用程序可以在 x86-64 上运行的原因。它旨在与 x86 兼容。明确一点,您不能在 32 位 Linux/x86 上运行 32 位 Linux/ARM 二进制文件。
    【解决方案2】:

    1) 处理器架构(加上目标库静态或动态)

    2) 是的

    32 位 Windows 应用程序将以 WOW 身份在 Windows 64 位平台上运行。

    【讨论】:

      【解决方案3】:

      如果您的(Windows)编译器的目标架构是 x86(32 位),那么它可以在任何 32 位和 64 位 Windows 7 上运行。但如果是 x86-64,它只能在 64 位 Windows 7 上运行。

      【讨论】:

      • Windows 不能在 x86/x86-64 以外的任何设备上运行吗?
      • @tobyodavies 取决于您是否包含 Windows NT(DEC Alpha)、Windows Phone 7(ARM Cortex 7)、Windows Embedded(x86、ARM、SuperH(我以前从未听说过))
      • ...Windows CE 也可以在 MIPS 上运行。
      【解决方案4】:

      要具体回答标题,请为两者编写代码。

      可执行文件包含特定于处理器的机器代码,以及许多有关如何加载/执行程序的操作系统元数据,这些元数据是特定于操作系统的。

      代码还可能(并且通常确实)包含对操作系统定义的函数的调用。因此,虽然它只是任何兼容 CPU 都能理解的完全普通的机器代码,但它会尝试调用仅存在于 Windows 上的代码。

      所以“本地”确实意味着两者。您为特定的操作系统(和所有兼容的操作系统)和特定的 CPU(和所有兼容的 CPU)编写代码。

      对于 Windows,您通常以特定版本的 Windows 为目标,然后程序将在该版本以及未来版本的 Windows 上运行。

      对于运行 Windows(和您的程序)的处理器,可执行文件包含 x86 机器代码,可以在 任何 x86 CPU 上执行,无论是来自 Intel、AMD、Via 还是其他任何公司else 多年来一直在制造兼容的处理器。

      【讨论】:

        【解决方案5】:

        无法看到您的代码,只有您可以告诉我们您是在为 32 位还是 64 位平台进行编码 - 例如,如果您将指针重新解释为 32 位 int,然后再返回指针,您正在为 32 位编码,而如果您使用诸如 int_ptr 之类的类型,则无论您的代码是为 32 位还是 64 位机器编译的,都是安全的。同样,为 Windows 桌面编码,您的编码可以假定机器的字节序。

        如果像您的示例一样,您为 32 位 Windows 7 编译该代码,那么它也将在 64 位 Windows 7 上运行。如果您使用 Windows 7 功能,它不会在早期版本上运行。微软非常擅长向后兼容,所以它可能会在以后的版本上运行。

        【讨论】:

          【解决方案6】:

          简短回答:不。

          更长:当你编译“本机代码”时,你是为特定的处理器架构编译的; MIPS、ARM、x86、68k、Sparc等。这些架构的字长可以是 8、16、32 和 64(也有例外)。此外,这些架构还可以进行代代相传,如 MMX、SSE、SSE2、Neon 等。

          您还需要考虑操作系统和可以使用的库,以及不同的调用约定。

          所以,不能保证。但是,如果您在 Windows 7 上使用 MSVC 编译,它几乎保证可以在 Windows 7 上运行。我认为它目前仅适用于 x86。

          【讨论】:

            猜你喜欢
            • 2017-01-25
            • 1970-01-01
            • 2011-10-16
            • 2019-05-10
            • 1970-01-01
            • 2015-07-21
            • 2012-04-06
            • 1970-01-01
            相关资源
            最近更新 更多