不同体系结构的汇编语言语法是否相同

Is Assembly Language syntax the same for different architectures

我知道我无法编写可以在所有机器上 run/compile 的汇编语言,因为它们有不同的指令集、操作码、寄存器等。我的问题是,即使指令集不同,是汇编语法(或它自己的语言)对于任何架构都一样吗?

有高级汇编器之类的术语https://en.wikipedia.org/wiki/High-level_assembler。 但是现在使用它没有任何意义,因为正如该页面所说:

High-level assemblers typically provide instructions that directly assemble one-to-one into low-level machine code as in any assembler

不同的体系结构通常会提供不同的功能,例如无法映射到其他程序集的条件指令。

如果需要创建可移植代码,请使用 C 语言。它为您提供了很多创建低级程序的可能性。如果你需要使用特定的架构特性,你可以使用内联汇编器(在 GCC 中它是扩展的 ASM)。

大多数 汇编程序之间存在广泛的相似之处。它总是面向行的,比如

[label:]  mnemonic [operand list]

虽然一些汇编器使用空格而不是逗号来分隔操作数。

一些历史悠久的汇编程序根据起始列而不是通过标签名称后的 : 来区分标签与助记符。 (因此它们强制执行良好的样式:最左侧的标签,缩进的助记符)标签定义符号名称以引用输出中的该位置。 (在许多汇编程序中,即使没有 :

,一行中的非助记符本身也被视为标签

一些语法将目标操作数放在最后,许多其他语法将其放在前面,但就将行解析为标记的基本语法而言,这是一个语义问题,而不是语法问题。

存在一些语法明显不同的汇编程序,例如 x86 HLA,其中的指令看起来像 C 函数调用。

大多数汇编器内置的宏处理器在不同的汇编器之间有很大的不同。指令名称如 .long vs. dd vs. dword.

经典 MIPS 汇编程序具有 ,而不是仅在当前位置发出填充。 (如果没有 .set noreorder,汇编程序实际上会优化您的代码以填充分支延迟槽。)同样,这不是句法,而是 .align 含义的一个很大的语义差异。

除此之外,asm 的每一行在某些部分中汇编为 0 个或更多字节的输出,与周围的行无关,这非常普遍。

My question is, even though the instruction set would be different, is the assembly syntax (or the language it self) the same for any architecture?

没有!

仅针对 x86,有十几种不同的 assemblers,每一种都有自己的独特性,使它们各自接受一种略有不同的语言 — GAS, MASM, NASM, TASM, FASM, ASM...很少有程序会 assemble 所有这些 x86 assemblers.

有 at&t 语法与 intel — 目标优先与目标最后。

指令有多种要求:.proc、.endp 等。

有英特尔漂亮的 byte ptr 语法来确定操作 size/width,与世界上大多数其他地方的 .b.w.l 操作码相比后缀(有时没有 .)。

一些 assemble 喜欢 : 标签后,其他人不允许(或需要 , 而不是)。

有些需要特殊字符来将寄存器名称与其他标识符区分开来(例如,有些需要 % 前缀,有些需要 $ 前缀),有些则不需要。

寻址模式的语法也有很大差异,例如在 ARM 的 [] 表示法中,括号后常量的异常位置表示指针变量更新。

这还没有涉及操作码的名称。

在英特尔上,我们使用 call 作为调用函数的指令(在捕获 return 地址时将 pc 传输到函数),jal 在 MIPS 和 RISC V 上,bsrjsrbljms

调用系统调用的术语,不同 syscallecalltrapscintswisvc 等..

简而言之,assemblers.

中没有语言、语法或句法的标准化

至于相似点,从广义上讲,有 if-goto 条件分支(和无条件分支)的概念作为控制流构造的机制,标签的概念作为分支目标和数据目标,每行一条指令(正如@Peter 提到的),带有单独操作数的助记符操作码——但这些相似之处是概念上的而不是句法上的。