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?