寄存器异或寄存器(汇编语言)

9

有时我们需要分析汇编代码(IA32),而经常会遇到这样的指令:

xor ax, ax

或者使用其他寄存器:xor dx, dxxor al, al,...这样做的确切含义是什么?(ax xor ax总是得到0?)

1
(xor是最好的方法) - Peter Cordes
3个回答

20

将寄存器设为0是一种常见的汇编语言习惯。

xor ax,ax 相当于 ax = ax ^ ax ,正如您已经注意到的那样,它有效地将 ax 设置为 0

如果我没记错的话,其主要优点是它的代码大小比mov ax,0要小。


谢谢,我想应该有别的方法而不是将它设置为0,因为如果我想要这样做,我会使用mov ax, 0,但如果它可以产生更短的代码,则确实更有意义。 - Aerus

2

xor %ax, %ax,如早前的评论所述,对应于ax = ax xor ax。这实质上将ax设置为0。此外,它还会影响/修改一些EFLAGS,例如OF、CF、SF、PF或ZF。在这种情况下,PF和ZF标志将被设置。

SF - 表示上一个操作的结果是否导致值的最高位设置为1。

PF - 表示上一个操作的结果的二进制表示中设置位数是奇数还是偶数。

ZF - 如果数学/逻辑操作的结果为零,则设置该标志;否则重置该标志。

以下示例使用GDB片段进行说明。

指令:xor %ax,%ax

"xor"之前:

(gdb) info registers
eax            0xaa55   43605
ecx            0x0  0
edx            0x80 128
ebx            0x0  0
esp            0x6f20   0x6f20
ebp            0x0  0x0
esi            0x0  0
edi            0x0  0
eip            0x7c02   0x7c02
eflags         0x2  [ ]
cs             0x0  0
ss             0x0  0
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0

在“xor”之后

(gdb) info registers
eax            0x0  0          --------------------> AX = 0          
ecx            0x0  0
edx            0x80 128
ebx            0x0  0
esp            0x6f20   0x6f20
ebp            0x0  0x0
esi            0x0  0
edi            0x0  0
eip            0x7c04   0x7c04
eflags         0x46 [ PF ZF ] --------------------> Flags Set
cs             0x0  0
ss             0x0  0
ds             0x0  0
es             0x0  0
fs             0x0  0
gs             0x0  0

欢迎来到SO。在我看来,这个答案比实用更详细。回答一个关于清零习惯用法的问题时,您不需要解释所有标志是如何工作的。只需留下一条评论指出,与“mov reg, 0”不同,xor会影响标志。由于您的答案将此问题弹出到最近活动的前面页面,我最终留下了一条评论,其中包含一个链接,指向一个更详细的关于为什么xor是清零寄存器的最佳方法的答案。(在大多数情况下,在您想要其标志结果的指令之前进行清零即可。) - Peter Cordes
谢谢。我同意它比需要的更详细。我现在注意到了。 - scanjee

2
这正是它的作用 - 将寄存器内容清零。

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