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仍可以认为是零成语,但除非你主动要保留寄存器,最好的高位字节路零alxor 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?

下一篇: The difference between MOV [reg],reg .. MOV reg,reg