x86程序集中cmove指令的用途?

mal*_*luz 13 x86 assembly

反汇编我遇到cmove指令的可执行文件.我已经在互联网上搜索了但是我发现它只是一个有条件的移动,如果源和目的地相等则会发生mov.我还没有理解的是为什么我需要它,因为它不会改变操作数.如果有必要的话,请你用一个例子来解释我的目的

谢谢

Guf*_*ffa 33

CMOVcc指令不比较的源和目标.它使用先前比较的标志(或设置标志的其他操作)来确定是否应该进行移动.

例; 这复制edxecxif eaxebx是否相等:

cmp eax, ebx
cmoveq ecx, edx
Run Code Online (Sandbox Code Playgroud)

这与以下相同:

cmp eax, ebx
jne skip
  mov ecx, edx
skip:
Run Code Online (Sandbox Code Playgroud)

  • @Guffa确实做了同样的事情,但第一个不关心分支预测失败。 (4认同)
  • 重要的一点:带有内存源操作数的`cmov` 像`cmoveq eax, [edx]` 是一个*无条件* 加载,它提供一个ALU 选择操作。它会[错误地址出错](/sf/ask/3783513191/)即使条件为假。`cmov` 的重点是拥有数据依赖而不是控制依赖(分支错误预测是可能的)。 (2认同)

Bre*_*dan 10

的目的cmov是允许软件(在某些情况下)避免分支。

例如,如果您有以下代码:

    cmp eax,ebx
    jne .l1
    mov eax,edx
.l1:
Run Code Online (Sandbox Code Playgroud)

..然后,当现代 CPU 看到jne分支时,它会猜测是否采用该分支,然后根据猜测开始推测性地执行指令。如果猜测错误,则会导致性能损失,因为 CPU 必须放弃任何推测执行的工作,然后开始获取并执行正确的路径。

对于有条件的移动(例如cmove eax,edx),CPU 不需要猜测将执行哪个代码,并且避免了错误预测分支的成本。但是,CPU 无法知道 in 的值是否eax会改变,这意味着后面依赖于条件移动结果的指令必须等到条件移动完成(而不是使用假定值和不拖延)。

这意味着如果可以轻松预测分支,则分支会更快;如果分支不能轻易预测,条件移动会更快。

请注意,从不严格需要有条件的移动(它总是可以用分支来完成)——它更像是一个可选的优化。