【问题标题】:does assembler output differ between operating systems?汇编程序输出在操作系统之间是否不同?
【发布时间】:2010-01-15 14:50:24
【问题描述】:

汇编程序从 C 源代码生成的汇编代码取决于其底层的 CPU 架构,例如 x-86。

那么简单的 C 源代码(包含 windows 和 linux 的通用函数调用)的汇编程序输出在操作系统之间会有所不同吗?

【问题讨论】:

  • 仅供参考,汇编程序只接受汇编指令并将其转换为机器代码。

标签: compiler-construction assembly


【解决方案1】:

这是一个很难回答的问题。如果我编译以下代码:

void f() {
  int x = 0;
  x = x + 1;
}

到两个平台上的 .o 文件(即未链接),我希望 x86 输出相同吗?

回答:可能。但如果不是,我不会感到惊讶。

【讨论】:

    【解决方案2】:

    汇编器确实依赖于底层架构,而不是操作系统本身。因此,汇编生成的代码在不同操作系统之间应该是相同的。

    不过,也有一些隐秘之处:

    1. 操作系统通常有不同的调用约定,可能会暴露给用户级应用程序。不过,这会在程序集中体现出来,因此程序集本身可能需要有所不同。

    2. 操作系统也会有不同的链接约定(例如静态链接与动态链接等)。所以最终的可执行文件可能会有所不同。

    3. 仅仅因为生成的文件相同,并不意味着生成的目标文件是可移植的。对于系统调用,中断处理程序 id 因操作系统而异。因此,如果您在 ASM 中对系统调用所需的中断进行硬编码,则该代码可能无法在不同的操作系统中运行。

    【讨论】:

    • 这里的问题集中在 C 和编译级别的细节上。组装过程基本上只是“通过人眼预处理器帮助传递到机器代码”。
    • @jldupont,是的。我回答了实际汇编程序的问题,而不是编译器。哦,好吧..
    【解决方案3】:

    汇编代码在具有相同机器操作码的平台之间可能不会有所不同,但它在汇编程序之间确实有所不同。 gas(GNU 汇编器)输出应该可以在任何支持它的平台下进行汇编,但不能在nasm(Netwide 汇编器)下编译。

    【讨论】:

    • hmmmm... CPU 就是 CPU,将人类可读的指令组装成机器可读的代码并不会改变这一点。
    【解决方案4】:

    如果您使用不同的编译器、同一编译器的不同版本或编译器的不同标志,那么所有的赌注都将失败。期望不同的汇编代码。如果您正在组装一个实际的 .asm 文件,那么生成的代码应该是相同的,但会以不同的方式打包到可执行文件中。在共享对象或 DLL 中调用函数显然取决于所使用的操作系统。

    【讨论】:

      【解决方案5】:

      输出会因编译器而异,包括从一个 gcc 版本到另一个版本,从一个发行版上的一个 gcc 到另一个,或在同一台机器上。基本上答案是肯定的,输出可以而且将会有很大的不同。说你可能一开始可能不会发现差异取决于代码和编译器选项,但你尝试的机器越多,32 位机器和 64 位,同一发行版中的细微更新差异等等。一个常见的误解是C 源代码是它的结尾,程序已经完成,性能已经完成,等等。现实情况是,即使在具有相同编译器的同一台机器上,从 C 到二进制还有大量的变体,每个变体都有功能和问题,可调试与否,性能与否,来自编译器的错误与否。对于足够大的程序,通过在编译器上使用不同的开关或使用更好的编译器,很容易证明性能提高了几倍。 不管你是编译成 asm 还是一个对象(取决于编译器,它可以并且将停止在一个临时的 asm 文件处,该文件被组装然后丢弃中间文件),指令的顺序和选择会有所不同。即使是一个稍微简单的程序也可以尝试使用或不使用调试内容(-g 我认为是,我从不使用它),以及各种优化级别 -O0、-O1、-O2、-O3。 8 种组合,你应该会得到一些不同的结果,尤其是从没有优化到一些优化。

      【讨论】:

        猜你喜欢
        • 2012-07-07
        • 1970-01-01
        • 1970-01-01
        • 2011-06-03
        • 2021-04-11
        • 2021-01-11
        • 1970-01-01
        • 2018-10-16
        • 1970-01-01
        相关资源
        最近更新 更多