Assembly x86汇编中cmove指令的用途?

Assembly x86汇编中cmove指令的用途?,assembly,x86,Assembly,X86,在反汇编可执行文件时,我遇到了cmove指令。我已经在互联网上搜索过了,但我只发现这是一个有条件的移动,如果源和目标相等,就会出现mov。我还不明白为什么我需要它,因为它不会改变操作数。其目的是什么?CMOVcc指令不比较源和目标。它们使用上一次比较(或设置标志的其他操作)中的标志,以确定是否应进行移动。() 榜样;如果eax和ebx相等,则将edx复制到ecx: cmp eax, ebx cmove ecx, edx 这与: cmp eax, ebx jne skip mov ecx,

在反汇编可执行文件时,我遇到了
cmove
指令。我已经在互联网上搜索过了,但我只发现这是一个有条件的移动,如果源和目标相等,就会出现
mov
。我还不明白为什么我需要它,因为它不会改变操作数。其目的是什么?

CMOVcc指令不比较源和目标。它们使用上一次比较(或设置标志的其他操作)中的标志,以确定是否应进行移动。()

榜样;如果
eax
ebx
相等,则将
edx
复制到
ecx

cmp eax, ebx
cmove ecx, edx
这与:

cmp eax, ebx
jne skip
  mov ecx, edx
skip:

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

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

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

对于有条件移动(例如,
cmove eax,edx
),CPU不需要猜测将执行哪些代码,并且避免了预测失误分支的成本。但是,CPU无法知道
eax
中的值是否会更改,这意味着依赖于条件移动结果的后续指令必须等待条件移动完成(而不是以假定值推测执行,并且不暂停)

这意味着,如果分支可以很容易地预测,那么分支可以更快;如果分支不容易预测,则条件移动可能会更快

请注意,条件移动从来都不是严格需要的(它总是可以通过分支来完成)-它更像是可选的优化

CMOVcc指令检查一个或多个状态的状态 EFLAGS寄存器中的标志(CF、OF、PF、SF和ZF)并执行 如果标志处于指定状态(或条件),则执行移动操作。A. 条件代码(cc)与每个指令关联,以指示 正在测试的状态。如果不满足该条件,则 不执行移动,继续执行指令 遵循CMOVcc指令

这些指令可以将16位或32位值从内存移动到内存 通用寄存器或从一个通用寄存器到 另一个不允许8位寄存器操作数的条件移动 支持

术语“更少”和“更大”用于比较签名 整数和术语“上面”和“下面”用于无符号 整数


@Guffa确实做了同样的事情,但第一个并不关心分支预测失败。重要的一点:
cmov
使用类似
cmoveq eax的内存源操作数,[edx]
是一个无条件加载,为ALU select操作提供数据。即使条件为假,它也会。而
cmov
的要点是具有数据依赖性而不是控制依赖性(分支预测失误是可能的)。(在前面的评论中输入错误:它是
cmove
而不是
cmoveq
。也许我想到的是手臂状态名称总是两个字母长,比如
eq
表示equal,不像x86的
e
表示equal)