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)