x86汇编中XOR的含义是什么?

54

我正在学习汇编语言,并且一直遇到 xor 这个指令,例如:

xor     ax, ax

它只是清除寄存器的值吗?


11
作为一种加强措施,这现在是在现代x86-64微架构中将寄存器清零的首选方法。它不需要任何执行单元(在解码器中处理),有效地消除了对dst=src寄存器的等待,同时也消除了部分标志寄存器的等待。 - Brett Hale
1
可能是重复的问题:有没有理由执行“xor eax,eax”? - Ciro Santilli OurBigBook.com
11个回答

70
在英语中,A XOR B被翻译为“A和B不相等”。因此,xor ax, ax会将ax设置为零,因为ax始终等于它本身。
A B | A XOR B
0 0 | 0
1 0 | 1
0 1 | 1
1 1 | 0

1
这真的很有帮助。这个答案在正则表达式方面对我很有帮助,所以以防万一: 在高级语言中,它将被翻译为类似于if(A != B)的东西。 - TheRookierLearner
10
A XOR B是构建更高级别结构的原始模块。它可以用来实现(A!=B),但它本身是一种明显不同的操作。同时,nightcracker所说的“在英语中‘A XOR B’会被翻译成‘A和B是否不相等’”只有当你从布尔零/非零的角度来看待结果时才是正确的。异或运算的一个流行应用是切换一个或多个位的某些输入位域:A XOR 1的结果是A的最低位的反转。 - phonetagger

26

xor reg, reg 经常用于清除寄存器。它可以作为 mov reg, 0 的替代方法。

在某些情况下,它比 mov reg, 0 更快(或更短)。

当然,XOR本身是一种异或(也称为互斥的排斥)操作(但在这里描述这样的基础知识是一种耻辱 - 使用Wikipedia)。


如果我运行 xor a,b,那么两个寄存器的值是否会根据条件被改变?我的意思是如果 a == b,那么在运行代码后,它们会变成 a = b = 0 吗? - Sunlight
1
@Sunlight 不是这样的。只有一个寄存器会受到影响(第一个)。 - Lukasz

18

xor ax, ax是将ax寄存器设置为0的最快方式,无论是在指令大小还是指令数量方面都是最快的。要详细了解它的工作原理,您需要对位运算有一些了解。

两个位之间的异或操作返回1,如果这两个位中只有一个为1;否则返回0。另一种解释方法是,如果这两个位不同,则返回1;否则返回0。

两个长度相同的二进制数之间的异或操作按位进行。将两个数进行XOR操作,得到一个由1组成的数字,其中相应操作数的位不同,当相应操作数的位相同时,结果为0。

从这些知识可以很容易地看出,如果两个操作数相同(例如,ax和ax),那么结果将为0。


2
在32位或64位模式下,使用xor eax, eax将ax寄存器清零更快。编码更短,没有对上16位的前一个值产生误导依赖关系。在现代CPU上的16位模式下,可能仍然最好使用xor eax, eax,因为这样做有许多使用已知清零惯用语的特殊好处。 - Peter Cordes

7

xor register, register通常用于“清零”寄存器,因为所有位都会相互比较:

0位保持为0。 1位变为0,因为1 XOR 1也是0。


5

xor = 异或。请参考维基百科的异或运算的定义。

如果你将一个寄存器与自身进行异或操作,它将清零该寄存器。

0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

以值41作为例子(用二进制表示):

    101001
xor 101001
  = 000000

3
A B | XOR
0 0 | 0
1 0 | 1
0 1 | 1
1 1 | 0

XOR指令对两个操作数中的每一对位执行上述操作。因此,0xFF xor 0xFF将是0x000x55 xor 0xAA将是0xFF。是的,xor ax ax会清除ax


2

很久以前我开始编程时,处理器和编译器上都没有异或运算符。当我接触到它时,我坚持使用以下描述:

  • or:如果a=1或b=1或两者都为1,则为true
  • xor:如果a=1或b=1但不是两者都为1,则为true

因此:

0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 1

并且

0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

2

在这种情况下,它将清除寄存器... XOR 是“异或”... 所以如果ax包含1010,你将它与1010异或,你将得到0000(已清除)。


2
如果我没记错的话,xor ax,ax 是一个一字节汇编指令,而 mov ax,0 至少需要3个字节,并且执行起来可能略微慢一些。它的解码时间肯定会比 xor 指令长。

根据位数而定,但是 xor (e)ax,(e)ax 是两个字节。 - Jens Björnhager
@Jens:当然,但问题是关于ax,而不是eax! - Sean
如果您处于16位模式,则指令为两个字节。如果是32位,则为3个字节。 - Jens Björnhager

1

它确定逻辑异或

0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0

因此,仅当一个表达式为真时才为TRUE,而不是两个表达式都为真。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接