为啥这么多汇编语法都包含逗号? [关闭]
Posted
技术标签:
【中文标题】为啥这么多汇编语法都包含逗号? [关闭]【英文标题】:Why do so many assembler syntaxs include commas? [closed]为什么这么多汇编语法都包含逗号? [关闭] 【发布时间】:2018-02-20 10:05:08 【问题描述】:我目前正在开发一个小型汇编程序,我一直想知道为什么我可以在网上找到的几乎所有汇编程序语法都使用逗号并且看起来像这样:
MOV eax, 123
我考虑这个的原因如下:
在我看来,空格作为分隔符似乎足够好,因此在可读性方面没有任何好处 将逗号作为(n 个额外的)分隔符使解析器更复杂/性能更低(即使只是略微) 我会认为,尤其是在早期,当汇编程序被引导或与其他汇编程序一起编写时,包含该语法会很麻烦我可以在网上找到的一个例外是这张来自***的图片: https://en.wikipedia.org/wiki/File:Motorola_6800_Assembly_Language.png
现在我不知道逗号是不是更现代的东西(x86/arm/etc. assemblers),但我的问题是:
何时、何地以及为何使用这种逗号语法?
【问题讨论】:
通用性、可用性、历史语法......它只是其中之一。 通常类似于<instr> <op1>[,<op2>[,<op3>]]
他们应该怎么做呢?在您的 6809 示例(LDA A #something
)中,您甚至无法判断指令在哪里结束(在这种情况下为“LDA A”),而#something 是 OP1,您会发现需要“LDA #something”的 6809 汇编器/反汇编器相反,这与上面提到的语法几乎相同。 6809 根本没有带有 2 个操作符的助记符(通常第一个是指令本身的一部分,如 LDA、LDB 等)
如果你有像 x86 这样复杂的寻址方案,并且允许宽松的空白,你可以得到像mov [ebx + edx*4], eax
这样的东西,其中有效地址定义中的额外空白字符会混淆基于空白的解析器。 Z80 已经有类似mov (ix+n),a
的指令,我不确定它们中的大多数是否允许内部空间,但如果它们允许,那么您将不得不解析括号的开头/结尾,或者使用逗号作为操作数分隔符。 (本例中的 Z80 代表早期历史,即逗号很常见,因为像“永远”这样)
不知道它是否相关,但在数学中你也使用逗号来分隔事物。
使用 whitespace-if-not-inside-brackets 比逗号更难解析。人类也不太清楚。 mov r10d, MAP_PRIVATE | MAP_ANONYMOUS
是我首先想到的。顺便说一句,x86 AT&T 语法可能看起来像add %eax, 16(%rdi,%rdx,4)
,所以它必须忽略括号内的逗号。但是寻址模式中允许的语法非常受限制,因此可能会使用单独的代码对其进行解析,从而可以轻松地将这些逗号从常规的逗号拆分解析中隐藏起来。
【参考方案1】:
如果您的汇编器支持符号表达式或架构具有复杂的寻址模式,则显式分隔符将消除歧义。
MASM 和 TASM 支持 mov var, 1
的语法 mov [var], 1
(大小从上下文推断)。mov var +2 -3
是什么意思? mov var+2, -3
还是 mov var, +2-3
? (两者都有效)。
如果寻址模式具有像(R1)+2
这样的形式(例如,对于某种写回),同样适用,MOV (R1) +3 +2
是不明确的。
在我看来,逗号使代码更具可读性,我的流程如下:
-
扫描第一个字并读取,这是操作码。
经过多年的训练,人类从历史开始就用空格分隔单词,我也学会了这种自动性。
用逗号分隔其余文本。
无需在心理上解析 LTR 或任何东西,只需找到外部逗号即可获得操作数的数量及其近似形式。
如果猜测的指令听起来不合适或出现任何问题,请执行完整的、缓慢的 LTR 解析行。
这让我可以快速浏览组装,但这只是我个人的看法。 最后,这是设计师的电话,Intel used it since the 8008,这是 4004 的芯片继任者,这是第一个(如果不是第一个)商用微芯片。 它可能只是卡住了。
处理逗号有点复杂,这是一个需要考虑的特殊情况,但归根结底是:这种语法是为人类设计的还是为计算机设计的?
在 mov (r0), r3
这样的表达式中,括号不需要配对(mov (r0, r3
仍然是明确的),这样解析起来会容易得多:
来自XKCD
【讨论】:
当您需要时,“upvote +2”在哪里?以上是关于为啥这么多汇编语法都包含逗号? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章