与 AT&T 相比,英特尔汇编语法的局限性 [关闭]

Posted

技术标签:

【中文标题】与 AT&T 相比,英特尔汇编语法的局限性 [关闭]【英文标题】:Limitations of Intel Assembly Syntax Compared to AT&T [closed] 【发布时间】:2010-11-01 15:17:58 【问题描述】:

对我来说,英特尔语法更容易阅读。如果我只专注于英特尔语法的汇编森林,我会错过任何东西吗?我有什么理由想切换到 AT&T(除了能够阅读其他人的 AT&T 程序集之外)?我的第一个线索是 gdb 默认使用 AT&T。

如果这很重要,我只关注任何关系汇编和语法可能对 Linux/BSD 和 C 语言有影响。

【问题讨论】:

【参考方案1】:

英特尔语法涵盖了所有内容(假设汇编器/反汇编器是最新的,最新的垃圾英特尔添加到他们的指令集中)。我敢肯定 at&t 也一样。

美国电话电报公司 movl -4(%ebp, %edx, 4), %eax mov eax, [ebp-4+edx*4] movl -4(%ebp), %eax mov eax, [ebp-4] movl (%ecx), %edx mov edx, [ecx] leal 8(,%eax,4), %eax lea eax, [eax*4+8] leal (%eax,%eax,2), %eax lea eax, [eax*2+eax]

...随着更复杂的指令,它会变得更复杂

'nuff 说。

【讨论】:

不,说的还不够。 发帖人已经表示他们更喜欢 intel 语法;对他们有好处;那么你想说服谁呢? @Hawken 不仅仅是发帖人会阅读答案。 我喜欢他提到双字长度示例的方式。请在单字节或短字节上写入内存操作数。【参考方案2】:

确实没有一个比另一个有优势。我不同意 Intel 语法更容易阅读,因为个人我讨厌 Intel 语法。请记住,AFAIK,所有 GNU 工具也可以选择使用 Intel 语法。

at&t noprefix                   intel
mov eax, -4(ebp,edx,4)          mov DWORD PTR[-4 +ebp +edx *4], eax
mov eax, -4(ebp)                mov DWORD PTR[-4 +ebp], eax
mov edx, (ecx)                  mov DWORD PTR[ecx], edx
lea (   ,eax,4), eax            lea eax, DWORD PTR[8 + eax*4]
lea (eax,eax,2), eax            lea eax, DWORD PTR[eax*2+eax]

...随着更复杂的指令,它会变得更复杂

'nuff 说。

PS:这个答案的存在主要是为了突出(恕我直言)在其他一些答案中的弱点,这些实际上不是答案,而是意见。当然,这个答案在现实中只是我的拙见。

PPS:我不讨厌 Intel 语法,我只是不在乎。

【讨论】:

我非常困惑。您是否暗示 at&t 语法永远不需要明确字长?你为什么要复制我的例子并添加字长和无用的 PTR 东西?另外,为什么您将我的差异更改为带有负左操作数的总和?是因为这就是指令的实际编码方式吗?用户很少需要真正关心这一点。在我使用的每个汇编程序中,您都可以省略 DWORD PTR,因为左操作数是 32 位的,而右操作数周围有方括号。 此外,IDA/ollydbg 甚至不会像你写的那样产生任何东西,所以,我很确定从机器代码到“好的”英特尔语法没有问题。所以你的例子看起来很做作,除了在汇编器或反汇编器的最简单的实现中我永远不会看到。另一方面,我模拟的 at&t 指令直接来自教学 at&t 语法的教程的第一段之一。 我得出的结论是,您是一台机器,因此您更喜欢直接反映指令的位编码的语法。 (这就是 at&t 语法所做的)。我还怀疑人们在使用 at&t 语法时会感觉更多 1337,因为它更晦涩难懂,尽管这并不是真正的优势...... @Longpoke 不,如果从上下文中可以清楚地看出,AT&T 语法不需要明确字长。与 intel 相同:如果从上下文中清楚操作数大小,则不需要 SOMEWORD PTR[]。但是,如果将立即数移动到内存位置(AT&T 的l 和英特尔的 DWORD PTR),则需要它。是的,我的例子非常做作——但你的例子也是如此。如果您仍然不明白为什么:您在 Intel 上遗漏了不需要的字号,但在 AT&T 中有它们。您选择操作数的方式使其在 Intel 中可以很好地对齐,但在 AT&T 中却没有这样做。 所以你是说-4(ebp,edx,4) 的东西比[4*edx+ebp-4] 好?我发现后者更直观。【参考方案3】:

这是专业精神的标志,您愿意适应正在使用的任何东西。两者都没有真正的优势。 intel 语法在 Microsoft 世界中很常见,AT&T 是 Linux/Unix 中的标准。由于两者都没有优势,人们倾向于在他们首先看到的任何东西上留下印记。也就是说,一个专业的程序员会提出这样的事情。使用他们在工作中或在您工作的领域中使用的任何东西。

【讨论】:

如何成为这些工具的“专业”用户,并知道如何改变它们以提高工作效率?英特尔语法 +1。 好吧,虽然我也赞成 Intel 语法,但他有一个观点——例如,考虑维护现有的 AT&T 代码。了解两者的方式绝对没有坏处。 虽然我也提倡两者都学习,但我会玩 Devil's Advocate 并建议您可以简单地编写 vim 脚本,将 *.s 文件自动转换为您选择的语法。 由于 intel 语法更易于阅读,因此 intel 语法具有优势。 "lea eax, [eax*4+8]" 比 "leal 8(,%eax,4), %eax" 有更好的客观可读性 @bug 嘿,你拼错了 emacs ;D【参考方案4】:

我的第一个汇编语言是 MIPS,我注意到它与 ATT 语法非常相似。所以我更喜欢 ATT 语法,不过没关系,只要你能看懂就行。

【讨论】:

MIPS 程序集仅在加载/存储指令的地址格式中类似于 AT&T 语法。但是 MIPS 只有一种用于加载/存储的简单寻址模式,而英特尔有更多,这使得这更加复杂。考虑上面发布的lea -0x30(%rcx,%rax,8),%eaxlea eax,[rcx+rax*8-0x30] jørgensen。与 AT&T 不同的是,MIPS 仍然像所有其他格式一样使用目标优先格式。另外,MIPS 编号不需要以 $ 为前缀,而且 MIPS 中的寄存器名称很短,所以像 AT&T 这样一路有 % 也不是很不舒服【参考方案5】:

它是“相同的语言”,因为它编译成相同的机器代码,具有相同的操作码等。另一方面,如果您使用 GCC,您可能想要学习 AT&T 语法,只是因为它是默认值——无需更改编译器选项等即可获得它。

我也开始使用 Intel-syntax x86 ASM(也在 DOS 上),并在最初切换到 C/UNIX 时发现它更直观。但是一旦你学会了 AT&T,它看起来就一样简单了。

我不会多想——一旦你了解了英特尔,就很容易学习 AT&T,反之亦然。实际的语言比语法更难进入你的脑海。因此,无论如何,只要专注于一个,然后在出现另一个时学习另一个。

【讨论】:

什么?因为 GCC 默认使用 at&t,所以没有理由学习 at&t 语法。尤其是当您可以将其切换到更直观的 Intel 语法时。 @longpoke 仅仅因为每个人都称它“更直观”而学习英特尔语法并不是一个更好的理由。其实这根本不是理由。 您说的都是对的,原因与 Verilog 和 VHDL 一直存在的原因相同。 @Hawken:是的。学习 Intel 语法的真正原因是 Intel 和 AMD 的手册使用它。没有像供应商手册那样详细使用 AT&T 语法的 ISA 参考手册,例如felixcloutier.com/x86/cmppd(摘自英特尔的 PDF)。还有像uops.info 和agner.org/optimize 这样的性能信息。我想我读到一些 Unix 供应商在某个时候提供了 AT&T ISA 参考,但它现在肯定已经过时并且不会涵盖 AVX 指令。 100% 同意这个答案:相同的机器代码,不同的表达语法,没什么大不了的。【参考方案6】:

GNU 汇编器 (GAS) 的主要语法是 AT&T。英特尔语法是一个相对较新的补充。 Linux 内核中的 x86 程序集采用 AT&T 语法。在 Linux 世界中,这是常见的语法。在 MS 世界中,Intel 语法更为常见。

就个人而言,我讨厌 AT&T 语法。有很多免费的汇编器(NASM、YASM)以及支持 Intel 语法的 GAS,所以在 Linux 中使用 Intel 语法不会有任何问题。

除此之外,这只是句法上的差异。两者的结果将是相同的 x86 机器码。

【讨论】:

同意并同意。使用 AT&T 语法应该是犯罪,它违反直觉且丑陋,为什么要为每个数字加上前缀并用 $ 和 % 注册,并以反向 SIB 表示法指定相对寻址,我一直在使用 Intel 语法两年了,仍然不明白为什么 AT&T 存在。 如果您要以粗体表示,至少提供一些证据说明为什么英特尔这么多更好。 @Hawken Haters 会讨厌 @Hawken 你是在暗示,因为他使用了粗体字,所以他以某种方式将他的观点作为事实陈述,如果他只是不理会粗体字,他就不会这样?无论如何,问题实际上是在邀请这种以舆论为主导的“辩论”,大概是为什么它现在关闭了! 英特尔的 ARM 语法怎么样?【参考方案7】:

确实没有一个比另一个有优势。我同意英特尔语法非常更易于阅读。请记住,AFAIK,所有 GNU 工具也可以选择使用 Intel 语法。

看起来你可以让 GDB 使用 Intel 语法:

设置拆解-风味intel

GCC 可以使用 -masm=intel 执行 Intel 语法。

【讨论】:

还有,echo set dis intel >> ~/.gdbinit AT&T 语法的可读性如何?我发现在操作数上使用大小后缀比使用“dword”更简洁。我还有什么遗漏的吗? lea -0x30(%rcx,%rax,8),%eaxlea eax,[rcx+rax*8-0x30] 的复杂 ATT。 + 和 * 的使用确实有助于 Intel 风格。 我认为它们的“卷积”是相等但不相同的:如果 ATT 是不透明的,那么 Intel 就是模棱两可的。虽然中缀算术对代数学生来说比较熟悉,但从语法上看不出该运算恰好有 4 个参数,或者只有其中一个可以相乘,而且在这两种情况下都不清楚乘数必须是2 的幂。 @Hawken 我发现 AT&T 的后缀比 Intel 的“ptr”好得多,因为您总是指定它并且它确实减少了错误的数量(至少对我而言)。关于其余的(例如 $ 和 % 符号).. 是的.. 它们并不令人愉快,这就是重点,但它们确实有一个优势:它是明确的,并且再次减少了错误。我会说一个适合阅读(英特尔),另一个适合写作(AT&T)。

以上是关于与 AT&T 相比,英特尔汇编语法的局限性 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 AT&T 语法时汇编程序崩溃 [重复]

AT&T汇编语法与x86语法基本区别

英特尔 AT&T 汇编程序的逐步执行?

Linux下AT&T汇编语法格式与Intel汇编语法格式异同

试图在汇编 at&t 中编写 strcpy,没有输出

关于 AT&T 语法汇编中的 cmp/jg、jle 等