【发布时间】:2017-11-08 21:06:21
【问题描述】:
我有一些在 Release 版本中编译的未知 C++ 代码,因此已对其进行了优化。我正在努力解决的问题是:
xor al, al
add esp, 8
cmp byte ptr [ebp+userinput], 31h
movzx eax, al
这是我的理解:
xor al, al ; set eax to 0x??????00 (clear last byte)
add esp, 8 ; for some unclear reason, set the stack pointer higher
cmp byte ptr [ebp+userinput], 31h ; set zero flag if user input was "1"
movzx eax, al ; set eax to AL and extend with zeros, so eax = 0x000000??
我不关心第 2 行和第 3 行。出于流水线的原因,它们可能按此顺序排列,恕我直言,与 EAX 无关。
但是,我不明白为什么我要先清除 AL,然后再清除 EAX 的其余部分。恕我直言,结果总是EAX = 0,所以这也可能是
xor eax, eax
相反。那段代码的优势或“优化”是什么?
一些背景信息:
我稍后会得到源代码。这是一个简短的 C++ 控制台演示程序,可能只有 20 行代码,所以没有什么我会称之为“复杂”的代码。 IDA 显示了该程序中的一个循环,但不是围绕这个部分。 Stud_PE 签名扫描未发现任何内容,但可能是 Visual Studio 2013 或 2015 编译器。
【问题讨论】:
-
它是否可能是从
cmp重复的循环的一部分,因此al在后续迭代中不再为零? -
@Jester:不,IDA 没有显示循环。
-
IDA 反汇编可能有问题(非常不可能,但可能)。也可能只是编译器错过了优化,可能被过于复杂的 C++ 源代码或一些无用的数据类型弄糊涂了,这些数据类型不能很好地编译。
xor eax,eax在这种情况下会更好,完全避免movzx。也可能是某种手动调整的“nop”填充,但我怀疑,使用普通的多字节nop变体更好。 -
@Ped7g:我稍后会得到源代码。这是一个简短的演示程序(C++ 控制台,可能只有 20 行代码)。 Stud_PE 签名扫描没有发现任何东西,但可能是 Visual Studio 2013 或 2015 编译器。
-
顺便说一句,如果它不在循环中,并且它不是某种高频交易机器人,或者其他具有实时要求和硬限制的东西,那么没关系,总可执行时间最多增加了 2-3 个周期......但它在编译器的优化阶段可能节省了数千个 CPU 周期;)