在反汇编可执行文件时,我遇到了cmove
指令。我已经在互联网上搜索了但我发现这是一个有条件的移动,如果源和目的地相等,则发生mov
。我还不明白为什么我需要它,因为它不会改变操作数。它的目的是什么?
答案 0 :(得分:30)
CMOVcc
说明不会比较来源和目的地。它使用先前比较的标志(或设置标志的其他操作)来确定是否应该进行移动。
实施例;如果edx
和ecx
相等,则会将eax
复制到ebx
:
cmp eax, ebx
cmoveq ecx, edx
这与:
相同cmp eax, ebx
jne skip
mov ecx, edx
skip:
答案 1 :(得分:1)
CMOVcc指令检查一个或多个状态的状态 EFLAGS寄存器(CF,OF,PF,SF和ZF)中的标志并执行 如果标志处于指定状态(或条件),则移动操作。一种 条件代码(cc)与每个指令相关联以指示 要测试的条件。如果不满足条件, 不执行移动,继续执行指令 遵循CMOVcc指令。
这些指令可以将16位或32位值从内存移动到 通用寄存器或从一个通用寄存器到 另一个。 8位寄存器操作数的条件移动不是 支持。
术语“较少”和“较大”用于比较带符号 整数,术语“上方”和“下方”用于无符号 整数。
https://wiki.cheatengine.org/index.php?title=Assembler:Commands:CMOVE
答案 2 :(得分:0)
cmov
的目的是允许软件(在某些情况下)避免分支。
例如,如果您具有以下代码:
cmp eax,ebx
jne .l1
mov eax,edx
.l1:
..然后,当现代CPU看到jne
分支时,将对是否采用该分支进行猜测,然后根据该猜测开始推测性地执行指令。如果猜测是错误的,则会导致性能下降,因为CPU必须丢弃任何推测执行的工作,然后开始获取并执行正确的路径。
对于有条件的移动(例如cmove eax,edx
),CPU无需猜测将执行哪个代码,从而避免了分支预测错误的代价。但是,CPU无法知道eax
中的值是否会更改,这意味着依赖于条件移动结果的后续指令必须等待条件移动完成(而不是通过推测性执行)具有假定值且不会停滞)。
这意味着,如果可以容易地预测分支,则分支可以更快;如果无法轻松预测分支,则条件移动会更快。
请注意,从不需要严格执行条件移动(始终可以通过分支来完成)-它更像是可选的优化。