[英]At&t syntax in Assembly?
我在组装中有多个非常小的问题,它们也相关,所以我在这个问题中收集了它们,而不是打开多个问题并向论坛发送垃圾邮件。
所有问题都与 Assembly At&t 语法有关:
为什么我不能写这样的东西:
cmp %eax, $0x2 jg goHere
为什么它不允许执行该比较操作(结果未保存在其中一个操作数中,因此不允许它没有意义...)注意:我知道我可以通过颠倒顺序并执行jl
来解决此问题而不是jg
。
在 att 语法中,这应该检查 0x2 是否大于 %eax。
为什么我可以写:
mov $41, %rax
虽然我不会写:
mov ($41), %rax
这很奇怪,有人告诉我在装配中使用大括号并不重要。
当在 memory 中保存一个字符串时,假设地址 0x100 中的“ABC”memory 应该是这样的:
0x100 - A 0x101 - B 0x102 - C
0x100 - C 0x101 - B 0x102 - A
对于 1,我对 x86 的原始设计没有特别了解,但我怀疑我们没有cmp %reg, $imm
的原因是因为cmp
和sub
之间的关系。 指令cmp $imm, %reg
的行为与sub $imm, %reg
完全相同,唯一的例外是cmp
减法结果不会写入目标%reg
,而是被丢弃。 但是减法的结果仍然由 CPU 在内部计算并用于设置标志。 (至少这在概念上是正确的,而且早期的 CPU 几乎肯定会进行完全减法;现代 CPU 可能有一些我不知道的优化。)
因此,这意味着一旦拥有sub
, cmp
几乎可以免费实施。 您可以使用几乎完全相同的电路和/或微码。 但是您仍然需要对指令进行解码,因此他们通过为cmp
提供与sub
几乎相同的编码,仅在一位上有所不同,从而使这一切变得简单。 例如, sub %reg, %reg/mem
是操作码 28h/29h 而cmp %reg, %reg/mem
是操作码 38h/39h,仅在第 4 位不同。这一位只是通知 CPU 是否将结果写入目标操作数或丢弃它。
这使得给cmp
与sub
完全相同的 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.