【问题标题】:Assembly language standard汇编语言标准
【发布时间】:2011-11-09 12:28:23
【问题描述】:

是否有定义汇编语言语法语义标准?就像语言 CISO 标准和语言 C#ECMA 标准一样吗?是只有一个标准,还是有更多?

我之所以问,是因为我 noticed 汇编语言代码在 WindowsLinux 上看起来 不同环境。我希望汇编语言不依赖于操作系统,它是唯一具有某些定义标准的语言,并且通过 assembler(汇编语言的编译器)被翻译成 机器指令 strong>处理器。

谢谢你的回答

【问题讨论】:

  • 感谢您的回答。都非常有用。

标签: standards assembly


【解决方案1】:

是的,有一个标准。

在 1980 年代之前构建汇编程序的人们选择了种类繁多的语法方案。

IEEE 社区提出了一个标准来试图避免这个问题:

694-1985 - IEEE Standard for Microprocessor Assembly Language

与软件世界中的许多事情一样,它过去和现在都在很大程度上被忽略了。

【讨论】:

  • 偶然注意到标准现在(2015)列为Withdrawn Standard
  • "...过去和现在在很大程度上被忽略了'。它实际上是一个有用的文档;只是没有人注意。
  • ...仍然可以从 IEEE 获得,无论是否撤销。
  • 我没有说它不可用。我说标准被简单地撤回了。
【解决方案2】:

最接近标准的是创建处理器/指令集的供应商将拥有描述该语言的文档,并且该供应商通常会提供某种汇编程序(程序)。一些供应商比其他供应商更注重细节和标准,所以你得到你所得到的。然后像这样的 intel/at&t 碰巧把事情搞砸了。再加上 gnu 汇编器喜欢弄乱它所支持的芯片的汇编语言,所以总的来说你会很混乱。

如果有一种汇编语言的使用可与 C 或 C++ 相媲美,那么您会期望一个组织尝试提出一个标准。部分问题仍然是,对于 C 语言之类的东西,在它到达硬件之前有一个解释,而对于汇编程序,则几乎没有,因此芯片供应商将根据市场因素制造他们想要制造的任何东西该标准必须被拖到与硬件相匹配的地方,而不是反过来由标准驱动供应商。

opencore 处理器可能是一种标准驱动的处理器,因为它不是特定于供应商的,也许它已经是。

使用汇编假设每个汇编程序/软件/工具的每个版本在同一指令集中以及不同指令集中都有自己的语法规则。 (这实际上是你用 C/C++ 得到的,但这是另一个话题)要么选择你最喜欢的工具并且只知道它,要么尝试记住所有工具的所有变体,或者我的偏好是尽量避免使用尽可能多的工具具体的语法和细微差别,并尝试找到可行的中间立场,或者至少有机会跨工具工作或移植。

【讨论】:

  • 我会认为经典的 K&R C 是装配标准 :-)
【解决方案3】:

不,没有标准。 甚至有两个different types of syntax:在 Windows 平台上占主导地位的 intel-syntax 和在 *nix 世界中占主导地位的 AT&T-sytanx。 关于维基百科中看起来不同的代码:windows 示例使用 Win32API,linux 示例使用0x80 interrupt 的系统调用。

【讨论】:

    【解决方案4】:

    汇编语言因处理器而异,因此没有标准。

    一般来说,特定处理器系列的“标准”汇编语言就是处理器设计者所说的那样。例如,x86 的“标准”语法就是英特尔所说的。但是,这并不妨碍其他人创建针对处理器的汇编语言变体,其语法或附加功能略有不同(Nasm 就是一个例子)。

    【讨论】:

      【解决方案5】:

      好吧,我不确定您是否在询问 x86 处理器的语法(我想是的,因为您提到了 NASM)。

      但是有两个共同的标准:

      • 最初用于 x86 平台文档的 Intel 语法
      • 在 Linux/Unix 世界中常见的 AT&T 语法。

      您提到的 NASM 更喜欢 Intel 语法。

      您可以在本文中找到一些语法差异的示例:http://www.ibm.com/developerworks/linux/library/l-gas-nasm/index.html

      【讨论】:

      • 英特尔语法有多种风格。 NASM 和 MASM 相似但有显着差异。 (例如 mov rdi, symbol 在 NASM 中是 mov r64, imm32,但在 MASM 中 mov r64, [mem] 即使没有方括号。)请参阅 stackoverflow.com/tags/intel-syntax/info 了解更多信息。
      【解决方案6】:

      没有,因为有许多不同的 CPU 具有不同的指令和其他特性,这完全取决于他们的设计者使用什么语法以及如何命名事物。而且几乎不需要对其进行标准化,因为汇编代码本质上是不可移植的,并且无论如何都需要针对不同的 CPU 重写。

      汇编语言本身不是特定于操作系统的,它是特定于 CPU 的,但是对于一个汇编例程来访问对您来说似乎是标准的东西(例如,一些在控制台中打印文本的子例程)需要特定于操作系统的代码。对于 MSDOS,您将使用 BIOS 和 DOS 中断服务例程(可通过 int 13h、int 10h、int 21h、int 33h 等指令在 x86 CPU 上调用),对于 Windows,您将使用 Windows'(可通过 int 2eh 和 sysenter 获得) /syscall 指令),对于 Linux,您将使用 Linux'(例如 int 80h)。它们都在不同的操作系统中以不同的方式实现,并且期望不同数量和种类的参数以及不同的位置(寄存器或内存)。你不能标准化这部分。您唯一能做的就是在操作系统功能之上构建一个兼容性/抽象层,以便从您的装配例程的角度来看它看起来是一样的。

      【讨论】:

        【解决方案7】:

        程序集语法/语言取决于 CPU 而不是操作系统。但是对于 x86 CPU 系列,有两种语法 AT&T(默认情况下由类似 Unix 的操作系统使用)和 Intel(由 Windows 和 DOS 等使用)

        然而,wiki 上的两个汇编示例都在做不同的事情。 windows 示例使用 WIN32 API 并显示一个消息框,因此所有函数参数都以相反的顺序压入堆栈,然后调用函数 MessageBox(),该函数轮流创建消息框。

        linux 示例使用write 系统调用将字符串写入标准输出。这里所有的“参数”都存储在寄存器中,然后int 0x80 创建一个“中断”,现在操作系统正在进入内核域,内核将字符串打印到标准输出。

        Linux 程序集可以重写如下:

        section .data
        msg:   db     "Hello, world!", 10
        .len: equ    $ - msg
        
        section .text
        
        extern write
        extern exit
        
        global _start
        _start:
                push msg.len
                push msg
                push dword 1
                call write
        
                push dword 0
                call exit
        

        上述程序集必须与 libc 链接,然后这将调用 libc 中的 write,而后者又执行与 wiki 上的示例完全相同的代码。

        另外需要注意的是,Windows 和类 Unix 操作系统在库和应用程序中使用不同的文件格式。

        类 Unix 系统使用 ELF http://en.wikipedia.org/wiki/Executable_and_Linkable_Format 而 windows 使用 PE http://en.wikipedia.org/wiki/Portable_Executable

        这就是为什么您会在 wiki 页面上的程序集中看到不同部分的原因。

        【讨论】:

        • 严格来说,AT&T 语法是 680x0 VAX 标准,在 x86 Unix 移植过程中沿用到 x86。由于供应商(英特尔)的语法更加系统化,因此卡住了。
        猜你喜欢
        • 2016-02-29
        • 1970-01-01
        • 2010-12-24
        • 2014-10-07
        • 1970-01-01
        • 2013-01-17
        • 2013-09-04
        • 1970-01-01
        相关资源
        最近更新 更多