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 中发生的情况,其中值在右侧计算,然后写入左侧。因此,考虑到阅读是从左到右的,写作从右到左,在“反向”方向上。AT&T 语法恢复到“正常”方向。至少他们是这么认为的;因为他们决定无论如何都要使用自己的语法,所以他们认为可以按照他们认为的“正确顺序”来使用操作数。这主要是一种约定,但不是不合逻辑的约定。C 约定模仿数学符号,除了数学是关于定义值(“让 x 是值 5”)而不是关于分配值(“一个名为“x”的插槽)。AT&T 的选择是有道理的。只有当您将 C 代码转换为汇编时,它才会令人困惑,该任务通常应该留给 C 编译器。
从历史的角度来看,问题 5 的最后一部分很有趣。x86 的 GNU 工具遵循 AT&T 语法,因为当时它们正试图在 Unix 世界中占据一席之地(“GNU”的意思是“GNU 不是 Unix”)并与 Unix 工具竞争;Unix 由 AT&T 控制。这是在 Linux 甚至 Windows 3.0 出现之前;PC 是 16 位系统。Unix 使用 AT&T 语法,因此 GNU 使用 AT&T 语法。
那么好问题是:为什么 AT&T 发现发明自己的语法很聪明?如上所述,他们有一些理由,这些理由并非没有道理。当然,使用您自己的语法的代价是它限制了互操作性。在那些日子里,C 编译器或汇编器作为一个单独的工具并没有真正的意义:在 Unix 系统中,它们应该由操作系统供应商提供。此外,英特尔在 Unix 世界中并不是一个大玩家。大型系统大多使用 VAX 或摩托罗拉 680x0 衍生产品。没有人想到 MS-Dos PC 会在 20 年后成为桌面和服务器世界的主导架构。