【问题标题】:How do assembly languages depend on operating systems?汇编语言如何依赖于操作系统?
【发布时间】:2011-10-15 02:51:23
【问题描述】:

由于汇编语言实现了独立于操作系统的 CPU 指令的符号表示,而汇编程序始终在某些操作系统下运行,我想知道汇编语言如何依赖于操作系统?例如,对于具有不同操作系统的同一个 CPU,汇编语言是否相同?谢谢!

【问题讨论】:

    标签: assembly operating-system


    【解决方案1】:

    正如其他人所指出的,系统调用和中断是不同的。我能想到另外一些不同之处。

    指令集在给定处理器上的所有操作系统中都是相同的,但可执行文件格式可能不同。例如,在 x86 上,Windows 使用 PE 格式,Linux 使用 ELF,MacOS 使用 Mach-O。这意味着这些平台上的汇编器必须以这些格式生成它们的输出,这是不同的。

    与此相关的是,不同操作系统的调用约定也可能不同。这可能只在您编写调用编译代码例程或被编译代码例程调用的汇编代码时,或者在某些编译代码中编写内联汇编程序时才重要。调用约定控制在函数调用期间哪些寄存器用于什么目的,因此不同的约定需要通过调用和被调用代码来不同地使用寄存器。他们还对堆栈指针的位置以及其他各种东西施加了约束。碰巧的是,在许多情况下,调用约定在历史上一直是跨操作系统一致性的罕见示例:我相信 Windows 和 UNIX 调用约定在 x86 上是相同的(并且都基于古老的 UNIX System V ABI 规范),并且在大多数其他架构上的操作系统之间是一致的。但是,现在 x86_64 上的 Windows 和 UNIX 之间的约定有所不同。

    此外,汇编语言使用的语法可能存在差异。同样在 x86 上,Windows 和 Linux 汇编器过去使用不同的语法,Windows 汇编器使用 Intel 发明的语法,而 Linux 汇编器(实际上是 GNU 汇编器)使用 AT&T 发明的传统 UNIX 语法。这些语法描述了相同的指令集,但编写方式不同。现在 GNU 汇编器也能理解 Intel 的语法,所以差别不大了。

    【讨论】:

    • 我也考虑过添加一个关于可执行格式的部分,但是 AFAIK 汇编器自己处理了这些,程序员不关心使用的格式。无论哪种方式,很好的答案,+1
    • @delnan:是的,你是对的,汇编器会处理输出格式。不同的格式是否会在您声明数据部分的方式或您可以使用的符号长度方面引入差异?如果不是,那么确实没有用户可见的差异。
    • 老实说,我不知道。符号长度不应该成为一个问题,只要它们不会太长(数千个字符),并且汇编程序应该能够抽象出部分细节,但话又说回来,我从来没有真的写了重要的汇编代码。
    【解决方案2】:

    可用的指令(当然还有每条指令的语义)取决于 CPU,而不是操作系统 - 所以在某种程度上,你是对的。

    但是对于大多数感兴趣的任务(例如 I/O),您必须与操作系统对话(进行系统调用)。在该级别不存在对这些事物的跨平台抽象(例如,您可以尝试使用libc,但即便如此,您也需要知道使用的调用约定,这可能会有所不同平台之间等等 - 最后,你必须自己做一些工作来构建这样一个抽象,所以在汇编编程的少数人中很少有人愿意尝试),做一些不可能的事情(独立于操作系统的)CPU 指令,你必须知道你正在为什么操作系统编程以及如何告诉那个操作系统去做。

    这不适用于内联汇编代码,例如C 代码,因为它主要用于以比编译器预期的更智能/更快的方式进行纯 CPU 密集型计算)。

    【讨论】:

    • 至于CPU,那么CPU代码一般都是标准化的吗?如果不是,那么在 CPU 上运行的代码不会在很大程度上无法在另一个 CPU 上运行吗?
    • @Pacerier 是的,几乎所有 CPU 都实现了几个指令集。例如,几乎所有 Intel 或 AMD CPU 都将支持 x86 和 x86-64 指令。
    • 那么编写一个独立于 CPU 且独立于操作系统的应用程序实际上是可行的吗?
    • @Pacerier 你从哪里得到的?正如我在答案中所写,许多任务,包括一些绝对必须被称为“应用程序”的任务, 依赖于操作系统。虽然只有几个 CPU 系列,但仍然不止一个 - 可以在您的台式计算机上运行的机器代码不会在您的手机或平板电脑上运行,甚至可能不会在服务器场上运行。
    • @Pacerier 不,不是在所有 CPU 上。 ARM CPU 与 x86 完全不同,MIPS CPU 也是如此(仅举三个流行的)。这三个系列不仅没有共同的指令,而且它们的指令编码也完全不同,因此即使它们共享指令,二进制文件也会不兼容。
    【解决方案3】:

    汇编语言不依赖于操作系统,而是依赖于 CPU 的指令集。

    仅当您调用 API 函数(例如,来自 MSVC 中的内联汇编代码的 Windows API 函数)时,您才会获得操作系统依赖项。

    【讨论】:

      【解决方案4】:

      汇编语言与它无关,您可以提出您的问题(xyz 语言如何依赖于操作系统)并使用 C、pascal、ada、fortran 和一长串其他语言并用同样的答案,语言与它无关。系统使用操作系统的调用约定调用操作系统才是最重要的,如果您使用与操作系统定义相同的语言或具有相同调用约定的语言,这使得生活更容易,但不会把你锁在任何东西上。几乎任何语言都可以使用,您可能很清楚,标准 C、C++ 等以及虚拟或运行时解释等 java、perl、python、shell 脚本、javascript 等。它们似乎都在我的至少电脑。 Somewhere (language specific) 是一个 shim,它使系统以操作系统定义的方式调用操作系统。 Asm 使其中一些语言的工作变得轻松,因为您不受任何规则的约束,您可以使用 asm 在语言调用约定和所需的操作系统调用之间制作垫片。同样,使用 asm 可以轻松连接到任何调用约定,无论是语言定义的还是操作系统定义的。

      正如已经回答的汇编语言独立于操作系统或任何其他在 cpu 上运行的软件。它直接与 cpu 的指令集相关联。现在有机器代码,处理器实际执行的位,那些不会改变,但是用来表示这些指令的ascii文件,语言可以改变,但不是因为cpu或操作系统,这些差异必须做与工具链。例如 x86 att 语法与 intel 语法。相同的指令集,相同的机器代码,不同的汇编语言。如果你环顾足够多的 tasm、masm 等,就会有许多用于 x86 的汇编器,每个汇编器都有自己的指令和其他工具链特定的细微差别。

      【讨论】:

        【解决方案5】:

        汇编语言应该是一样的;正如您所指出的,指令集仅取决于 CPU 及其架构设计。我相信,当你开始调用不同的操作系统时,你开始遇到麻烦,例如中断(通常用于 I/O),这绝对意味着为例如编写的程序。 MSDOS 不能用于例如Solaris(也许是个坏例子)。

        【讨论】:

          【解决方案6】:

          汇编程序将助记符(例如jumpmovadd 等)从汇编语言翻译成机器指令。机器指令完全依赖于硬件(它们代表硬件/CPU指令集)。

          如果您想提出一种汇编语言,您还需要设计/编写一个汇编程序来映射到机器指令。从这个意义上说,如果您针对给定的机器架构,汇编器应该生成特定于机器的代码,而不是特定于操作系统的代码。然而,汇编器实现可能(并且通常)特定于操作系统,因为它生成的输出程序(Unix 可执行文件与 Windows 可执行文件不同,甚至虽然底层机器指令集是 x86,例如)。

          请参阅here 我的意思。

          【讨论】:

            【解决方案7】:

            操作系统无关紧要。你可以在不同的操作系统上使用相同的汇编器,你可以在相同的操作系统上使用不同的编译器,嘿,你甚至可以交叉编译,针对不同的系统。

            【讨论】:

              猜你喜欢
              • 2017-12-25
              • 2012-06-17
              • 2021-10-28
              • 1970-01-01
              • 1970-01-01
              • 2011-03-22
              • 2020-04-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多