不同体系结构的汇编语言语法是否相同
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 上,bsr
、jsr
或 bl
、jms
等
调用系统调用的术语,不同 syscall
、ecall
、trap
、sc
、int
、swi
、svc
等..
简而言之,assemblers.
中没有语言、语法或句法的标准化
至于相似点,从广义上讲,有 if-goto 条件分支(和无条件分支)的概念作为控制流构造的机制,标签的概念作为分支目标和数据目标,每行一条指令(正如@Peter 提到的),带有单独操作数的助记符操作码——但这些相似之处是概念上的而不是句法上的。
我知道我无法编写可以在所有机器上 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 上,bsr
、jsr
或 bl
、jms
等
调用系统调用的术语,不同 syscall
、ecall
、trap
、sc
、int
、swi
、svc
等..
简而言之,assemblers.
中没有语言、语法或句法的标准化至于相似点,从广义上讲,有 if-goto 条件分支(和无条件分支)的概念作为控制流构造的机制,标签的概念作为分支目标和数据目标,每行一条指令(正如@Peter 提到的),带有单独操作数的助记符操作码——但这些相似之处是概念上的而不是句法上的。