XOR AL,AL + MOVZX EAX,AL在XOR EAX,EAX上的优势?
我有一些未知的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编译器。
xor al,al在大多数CPU上已经比xor eax,eax慢。 例如,在Haswell / Skylake上,它需要一个ALU uop,并且不会破坏对eax / rax旧值的依赖。 AMD CPU或Atom / Silvermont也同样糟糕。 (好吧,也许不是同样的原因,因为AMD不会在问题/重命名时消除xor eax,eax ,但它仍然具有错误的依赖关系,可以使用任何使用的eax最后序列化新的依赖关系链)。
在CPU的那些重命名al从寄存器(英特尔预IvyBridge的),在其余分别xor al,al仍可以认为是零成语,但除非你主动要保留寄存器,最好的高位字节路零al是xor eax,eax 。
在上面做movzx只会让它变得更糟。
我猜你的编译器有点困惑,并决定它需要一个1字节的零,但后来意识到它需要将其提升到32位。 xor设置标志,所以它不能在cmp之后xor或,并且它没有注意到它可能在cmp之前只有异或eax 。
无论是这个,还是像Jester的建议, movzx是一个分支目标。 即使情况如此, xor eax,eax仍然会更好,因为在此代码路径上无条件地扩展到eax。
我很好奇编译器是从什么来源制作的。
链接地址: http://www.djcxy.com/p/85899.html上一篇: Any advantage of XOR AL,AL + MOVZX EAX, AL over XOR EAX,EAX?
