在 x86_64 中,如果条件为假,32 位 cmov 是否清除最高位?

apt*_*002 3 assembly x86-64

在 x86 上的 64 位模式下,大多数 32 位算术运算会清除目标寄存器的前 32 位。如果算术运算是“cmov”指令,并且条件为假怎么办?(我看过的参考手册中似乎没有涵盖这种情况)。

Pet*_*des 5

它总是零扩展到目标,就像所有写入 32 位寄存器的指令一样。

将 CMOV 视为始终写入其目的地:它是一个 ALU 选择操作(3 个输入:2 个整数操作数和标志,1 个输出)。

当条件为假时,它不像 ARM 32 位模式谓词指令那样真正像 NOP。

(出于同样的原因,即使条件为假,也cmovcc reg, [mem] 始终加载内存操作数,并且不会对错误地址进行故障抑制。同样,条件不是移动本身,而是移动条件的结果 -选择操作。AArch64 为它们的相同指令选择了一个更好的名称,csel.)


有一种情况下一个32位的目的地可以不被零扩展:bsrbsf r32,r/m32当所述源是零个叶目的地未修饰。(仅由 AMD 记录如果第二个操作数包含 0,则指令将 ZF 设置为 1 并且不会更改目标寄存器的内容。),但也由 Intel 实现)。至少在 Intel CPU 的实践中,这包括在像bsf eax, ecx. 我没有测试过 AMD。

(这就是为什么 BSF 和 BSR 对目标具有“错误”依赖关系:无分支地实现此行为需要真正的依赖关系。它只是英特尔上 LZCNT/TZCNT/POPCNT 的错误输出依赖关系,它们在同一执行单元上运行但总是覆盖它.)

维基百科)声称 Intel 和 AMD 在bsf r32, r/m32. 他们似乎在说英特尔(或者可能是 AMD;措辞有些含糊不清)在 source=0 的情况下未定义高位,而不是未修改。

在我对 Sandybridge 系列和 Core 2 的测试中,它似乎始终未修改,但我无法访问 P4 Nocona / Prescott,这是第一代 IA-32e 微体系结构。

撰写该内容的维基百科编辑器可能只是误解了英特尔的文档,该文档称在这种情况下整个目标寄存器是“未定义的”。(但对于英特尔来说,在硅片上超出他们在纸上的保证正常的,因此他们关心的现有软件,例如 Windows,可以继续工作)。IDK,如果该声明还有其他来源,那么我想 [需要引用] 在这里真的很合适。