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

问题描述:

我不是最有经验的汇编程序员,我遇到了“cqo”,“cdq”和“cwd”指令,这些指令都是有效的x86_64汇编。“cqo”,“cdq”和“cwd”x86_64指令。为什么不使用cqo?

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

编辑: 最初开始研究这个,当计算一位数字的绝对值。

例如,如果我们有-9值在人:

cwd 
xor al,dl 
sub al,dl 

与具有它作为一个32位的值,并计算

cdq 
xor eax,edx 
sub eax,edx 

,或者如果我们有一个64位的值 - 9

cqo 
xor rax,rdx 
sub rax,rdx 

如果原始值是64位,并且由值-9到9组成,实际上它们看起来都是相同的。

+0

嗨,欢迎来到Stack Overflow。请提供一些使用示例和具体用例,以便我们提供帮助。尽量提供尽可能多的信息,以便我们了解情况。 :) – Selfish

+0

好的,我添加了一些例子。我还听说在32位机器中,使用32位的值而不是字节的速度更快。在x86_64的情况下,对于64位值,这是真的吗?还是真的? – Husky

+0

看起来很棒!现在很明显,我已经投票提出了你的问题,希望能够得到更多的关注。 – Selfish

如果您的值已被符号扩展以填充16位以上的rax,则您只有一个选择。

如果在ax中有一个带符号的16位int,但eax的upper16不为零或为零,则必须继续使用16位指令。 cdq会根据eax顶部的垃圾位设置edx,而不是ax中的值的符号位。同样,如果您使用32位ops在eax中生成带符号的32位整数,则upper32将被清零,而不是符号扩展。如果可以,使用cdq。如果您需要在rdx中设置所有64位,则可能需要cqo


请参阅http://agner.org/optimize/了解如何在x86上快速运行asm。 32位操作数大小是64位模式下的默认值,因此16或64位操作数需要额外的前缀。这意味着更大的代码大小,这意味着更糟糕的I-CACHE效率(并且通常前Sandybridge CPU上的解码瓶颈更多; SnB的UOP CACHE通常意味着解码不是问题)。以前的注册内容,因为写斧头并没有清除其余的rax。幸运的是,AMD64在设计时考虑了乱序CPU,因此避免了重复那些不便于高性能的设计选择by clearing the upper32 when writing the low 32bits of a GP reg。 (当AMD64被设计时,x86 CPU已经使用了OOO,不像ax被扩展到eax)。

+2

[为什么大多数x64指令会将32位寄存器的上半部分清零](http://*.com/q/11177137/995714) –

+1

@LưuVĩnhPhúc:谢谢,我懒得查找并链接那个问题,这我知道存在。 –

+0

谢谢,这是非常有用的信息和链接。 – Husky