Assembly 有关美国电话电报公司的问题;T x86语法设计 有人能解释一下为什么AT&T语法中的每个常量前面都有一个“$”吗 为什么所有寄存器都有“%” 这是不是又一次试图让我做很多蹩脚的打字 另外,我是唯一一个发现:16(%esp)与[esp+16]相比真的违反直觉的人吗 我知道它编译成相同的东西,但为什么有人不需要输入大量的“$”和“%”呢为什么GNU选择这个语法作为默认语法 另一件事,为什么at&t语法中的每条指令前面都有:l我确实知道操作数的大小,但是为什么不让汇编程序来解决呢? (我是否希望对不是该大小的操作数执行movl操作?) 最后一件事:为什么mov参数是颠倒的

Assembly 有关美国电话电报公司的问题;T x86语法设计 有人能解释一下为什么AT&T语法中的每个常量前面都有一个“$”吗 为什么所有寄存器都有“%” 这是不是又一次试图让我做很多蹩脚的打字 另外,我是唯一一个发现:16(%esp)与[esp+16]相比真的违反直觉的人吗 我知道它编译成相同的东西,但为什么有人不需要输入大量的“$”和“%”呢为什么GNU选择这个语法作为默认语法 另一件事,为什么at&t语法中的每条指令前面都有:l我确实知道操作数的大小,但是为什么不让汇编程序来解决呢? (我是否希望对不是该大小的操作数执行movl操作?) 最后一件事:为什么mov参数是颠倒的,assembly,x86,att,intel-syntax,Assembly,X86,Att,Intel Syntax,这不是更符合逻辑吗: eax = 5 mov eax, 5 其中at&t为: mov 5, eax 5 = a (? wait what ?) 注: 我不是想耍花招。我只是不理解他们所做的设计选择,我试图了解他们为什么这么做。1-2,5:他们可能选择在寄存器前面加前缀,这样更容易解析;在第一个字符处,您直接知道它是什么类型的标记 4:没有 6:同样,可能是为了让解析器更容易确定要输出的指令 7:实际上,这在语法意义上更有意义,把什么移到哪里。也许mov指令应该是ld指令 别误会我的意思,我认

这不是更符合逻辑吗:

eax = 5
mov eax, 5
其中at&t为:

mov 5, eax
5 = a (? wait what ?)
注:
我不是想耍花招。我只是不理解他们所做的设计选择,我试图了解他们为什么这么做。

1-2,5:他们可能选择在寄存器前面加前缀,这样更容易解析;在第一个字符处,您直接知道它是什么类型的标记

4:没有

6:同样,可能是为了让解析器更容易确定要输出的指令

7:实际上,这在语法意义上更有意义,把什么移到哪里。也许mov指令应该是ld指令


别误会我的意思,我认为AT&t语法很糟糕。

1、2、3和5:符号有点多余,但我发现在汇编中开发时它是一件好事。冗余有助于阅读。关于“让汇编程序去理解”的观点很容易变成“让读代码的程序员去理解”,我不喜欢当我在读代码的时候。编程不是只写的任务;甚至程序员自己也必须阅读自己的代码,语法冗余也有很大帮助

另一点是“%”和“$”意味着可以在不破坏向后兼容性的情况下添加新寄存器:添加时没有问题,例如,一个名为
xmm4
的寄存器,因为它将被写为
%xmm4
,不能与一个名为
xmm4
的变量混淆,该变量将在没有“%”的情况下写入

至于键入的数量:通常,在汇编中编程时,瓶颈是大脑,而不是手。如果“$”和“%”使您慢下来,那么您的思考速度可能比通常认为人类可以完成的要快,或者,更可能的是,您手头的任务过于机械,不应该在汇编中完成;它应该留给一个自动代码生成器,俗称“C编译器”

添加“l”后缀是为了处理汇编程序“无法”理解它的某些情况。例如,此代码:

mov  [esp], 10
是不明确的,因为它不能告诉您是要写入值为10的字节,还是要写入具有相同数值的32位字。英特尔语法随后要求:

mov  byte ptr [esp], 10
想想看,这很难看。at&T的员工想让事情变得更加理性,因此他们提出:

movb   $10, (%esp)
他们更喜欢系统化,到处都有“b”(或“l”或“w”)后缀。请注意,后缀并不总是必需的。例如,您可以编写:

mov   %al, (%ebx)
让GNU汇编器“弄明白”,既然您在谈论“%al”,那么移动是针对单个字节的。它真的有效!然而,我仍然发现指定大小更好(它确实有助于读者,程序员自己是自己代码的首要读者)

对于“反转”:它是另一种方式。英特尔的语法模仿C语言,在C语言中,值在右边计算,然后写入左边的值。因此,考虑到阅读是从左到右的,书写是从右到左,以“相反”的方向进行的。AT&T语法恢复为“正常”方向。至少他们认为是这样;由于他们决定使用自己的语法,他们认为可以按照他们认为的“正确顺序”使用操作数。这主要是一种惯例,但不是不合逻辑的。C约定模仿数学符号,除了数学是关于定义值(“让x为值5”)而不是分配值(“我们将值5写入一个称为“x”的槽中”)。AT&T的选择是有道理的。只有当您将C代码转换为汇编代码时,这才令人困惑,这项任务通常应该留给C编译器完成

从历史的角度来看,问题5的最后一部分很有趣。x86的GNU工具遵循AT&T语法,因为当时,它们试图在Unix世界占据一席之地(“GNU”表示“GNU不是Unix”),并与Unix工具竞争;Unix在AT&T的控制下。这是在Linux甚至Windows3.0出现之前;PC是16位系统。Unix使用AT&T语法,因此GNU使用AT&T语法


好问题是:为什么AT&T发现发明自己的语法是明智的?如上所述,他们有一些理由,这些理由并非没有道理。当然,使用自己的语法的代价是它限制了互操作性。在那些日子里,C编译器或汇编程序作为一个单独的工具没有任何实际意义:在Unix系统中,它们是由操作系统供应商提供的。此外,英特尔在Unix世界中也不是一个大玩家;大型系统大多使用VAX或摩托罗拉680x0衍生品。没有人想到,20年后,MS Dos PC将成为桌面和服务器世界的主导架构。

AT&T语法与Intel相反的操作数顺序很可能是因为最初开发Unix的PDP-11使用相同的操作数顺序


英特尔和DEC只是选择了相反的顺序。

GNU汇编程序的AT&T语法可以追溯到Unix汇编程序1,即
Last thing: why are the mov arguments inverted?