繁体   English   中英

汇编中的 At&t 语法?

[英]At&t syntax in Assembly?

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

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

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

     cmp %eax, $0x2 jg goHere

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

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

  1. 为什么我可以写:

     mov $41, %rax

    虽然我不会写:

     mov ($41), %rax

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

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

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

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

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

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

这使得给cmpsub完全相同的 forms 变得很自然:

  • 我们有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的现有编码平行。 设计者可能决定不浪费解码晶体管和操作码空间来创建一个,因为毕竟它不会真正提供任何新功能: cmp实际上总是与条件跳转(或后来的条件集)结合使用,并且在在这种情况下,您始终可以通过使用cmp $imm, %reg并在随后的条件跳转/设置中反转测试来实现相同的目的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM