鉴于https://stackoverflow.com/a/33668295中详述的考虑因素,这似乎xor reg, reg
是将寄存器归零的最佳方法。但是当我检查真实世界的汇编代码(例如 Windows 引导加载程序代码、IIRC)时,我看到xor reg, reg
并sub reg, reg
使用了这两个代码。
为什么sub
完全用于此目的?sub
在某些特殊情况下是否有任何理由偏爱?例如,它设置的标志与xor
?
鉴于https://stackoverflow.com/a/33668295中详述的考虑因素,这似乎xor reg, reg
是将寄存器归零的最佳方法。但是当我检查真实世界的汇编代码(例如 Windows 引导加载程序代码、IIRC)时,我看到xor reg, reg
并sub reg, reg
使用了这两个代码。
为什么sub
完全用于此目的?sub
在某些特殊情况下是否有任何理由偏爱?例如,它设置的标志与xor
?
差异:
sub reg,reg
记录为设置 AF=0(BCD 半进位标志,从位 3 到位 4)。 XOR使 AF 未定义。架构效果在其他方面完全相同,只留下可能的性能差异。AF 几乎无关紧要,通常只有在下一条指令是aaa
什么时。sub
-zeroing 在一些 CPU 上比 xor-zeroing 慢(例如 Silvermont,正如我在您链接的答案中指出的那样),但大多数 CPU 的性能相同。当然,两者都具有相同的 2 字节大小。我猜这只是手写 asm 的不同作者,他们中的一些人sub
可能更喜欢没有意识到某些 CPU 只是特殊情况的异或。除非他们想要保证清除 AF 标志,否则sub
可能是有意的。就像可能初始化事物并希望在可能使用pushf
.
XOR 使 AF 未定义仍然意味着它将是 0 或 1,你只是不知道哪个。(不像 C 未定义的行为)。实际结果可能取决于 CPU 型号、输入值,甚至可能是某处的一些杂散位。
在识别sub
归零习惯用法的现代 CPU 中,它将为零,因此 CPU 可以完全相同地处理异或归零和子归零,包括 FLAGS 结果。
两者xor reg, reg
和在许多现代 x86 处理器上sub reg, reg
都被认为是归零习惯用法。两者的效果是相同的,使用一个比另一个没有优势。