“cqo”,“cdq”和“cwd”x86_64指令。为什么不只使用cqo?

时间:2015-11-19 19:38:12

标签: assembly x86-64

我不是最有经验的汇编程序员,我遇到了“cqo”,“cdq”和“cwd”指令,它们都是有效的x86_64程序集。

我想知道在较小的值上操作时使用cdq或cwd是否有任何优点。性能有所不同吗?

编辑: 在计算一位数的绝对值时,最初开始研究这个问题。

例如,如果我们在al:

中有-9值
cwd
xor al,dl
sub al,dl

VS。将其作为32位值并计算

cdq
xor eax,edx
sub eax,edx

或者如果我们有-9

的64位值
cqo
xor rax,rdx
sub rax,rdx

如果原始值是64位并且值为-9到9,那么它们看起来都是一样的。

1 个答案:

答案 0 :(得分:4)

如果您的值已经过符号扩展以填充超过16位的rax,则只能选择。

如果你有一个有符号的16位int in ax,但是eax的upper16是未知或为零,你必须继续使用16bit指令。 cdq将根据eax顶部的垃圾位设置edx,而不是ax中值的符号位。

同样,如果您使用32位操作在eax中生成带符号的32位int,则upper32将被清零,而不是符号扩展。

如果可以,请使用cdq。如果需要在rdx中设置所有64位,则可能需要cqo

请参阅http://agner.org/optimize/以了解如何在x86上快速运行asm。 32位操作数大小是64位模式的默认值,因此16或64位操作数需要额外的前缀。这意味着更大的代码大小,这意味着更高的I-cache效率(并且通常在Sandybridge之前的CPU上有更多的解码瓶颈; SnB的uop缓存通常意味着解码不是问题。)

16bit也对寄存器的先前内容具有错误依赖性,因为写入ax不会清除rax的其余部分。幸运的是,AMD64在设计时考虑了无序CPU,因此它避免重复那些对高性能by clearing the upper32 when writing the low 32bits of a GP reg不方便的设计选择。 (当设计AMD64时,x86 CPU已经使用了OOO,与ax扩展到eax时不同)。