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