汇编中的 At&t 语法?

At&t syntax in Assembly?

我在汇编中有多个非常小的问题,它们也相关,所以我将它们收集在这个问题中,而不是打开多个问题并在论坛上发垃圾邮件。

所有问题都与 Assembly At&t 语法有关:

  1. 为什么我不能写这样的东西:

     cmp %eax, [=10=]x2
     jg goHere
    

为什么它不允许进行比较操作(结果未保存在其中一个操作数中,因此不允许它没有意义...)注意:我知道我可以通过以下方式解决此问题颠倒顺序并执行 jl 而不是 jg.

在 att 语法中,这应该检查 0x2 是否大于 %eax。

  1. 为什么我会写:

     mov , %rax
    

    虽然我不会写:

     mov (), %rax
    

这很奇怪,有人告诉我在汇编中使用大括号并不重要。

  1. 当在内存中保存一个字符串时,假设地址 0x100 中的“ABC”内存应该是这样的:

    0x100 - 一个 0x101-B 0x102 - C

    0x100-C 0x101-B 0x102-A

对于1,我对x86的原始设计没有特别了解,但我怀疑我们没有cmp %reg, $imm的原因是因为cmp和[=之间的关系12=]。指令 cmp $imm, %reg 的行为与 sub $imm, %reg 完全相同,唯一的例外是 cmp 的减法结果不会写入目标 %reg,而是被丢弃。但是减法的结果仍然由 CPU 内部计算并用于设置标志。 (至少这在概念上是正确的,早期的 CPUs 几乎肯定做了完全减法;现代 CPUs 可能有一些我不知道的优化。)

所以这意味着一旦您拥有 subcmp 几乎可以免费实施。您可以使用几乎完全相同的电路 and/or 微代码。但是您仍然需要对指令进行解码,因此他们通过为 cmp 提供与 sub 几乎相同的编码,仅在一位上有所不同,从而使这也变得容易。例如,sub %reg, %reg/mem 是操作码 28h/29h,而 cmp %reg, %reg/mem 是操作码 38h/39h,仅在第 4 位不同。该位仅指示 CPU 是否将结果写入目标操作数或丢弃它。

这使得 cmpsub 完全相同的形式变得很自然:

  • 我们有 sub %reg, %reg 所以有 cmp %reg, %reg.

  • 我们有 sub %reg, mem 所以有 cmp %reg, mem.

  • 我们有 sub mem, %reg 所以有 cmp mem, %reg.

  • 我们有 sub $imm, %reg 所以有 cmp $imm, %reg.

  • 甚至还有一个特殊的短编码sub $imm, %al/%ax/%eax/%rax,它有一个平行的cmp $imm, %al/%ax/%eax/%rax.

但是没有 sub %reg, $imm 的编码,因为那是无稽之谈,所以 cmp %reg, $imm 需要一种新的编码,这种编码不会与 sub 的现有编码平行.设计师大概决定不浪费解码晶体管和操作码 space 来创建一个,因为毕竟它不会真正提供任何新功能:cmp 实际上总是与条件跳转(或稍后,条件集),在这种情况下,您始终可以通过使用 cmp $imm, %reg 并在后续条件 jump/set.

中反转测试来实现相同的目的