【发布时间】:2012-01-02 08:29:15
【问题描述】:
有时我们不得不分析汇编代码(IA32), 而且我经常遇到这样的指令:
xor ax, ax
或者也可以使用其他寄存器:xor dx, dx, xor al, al, ...
这究竟是做什么的? (ax xor ax 总是给出 0 ?)
【问题讨论】:
-
stackoverflow.com/questions/33666617/…(异或是最好的办法)
有时我们不得不分析汇编代码(IA32), 而且我经常遇到这样的指令:
xor ax, ax
或者也可以使用其他寄存器:xor dx, dx, xor al, al, ...
这究竟是做什么的? (ax xor ax 总是给出 0 ?)
【问题讨论】:
将寄存器设置为 0 是一种常见的汇编程序习惯用法。
xor ax, ax 对应于 ax = ax ^ ax,正如您已经注意到的,实际上是 ax = 0。
如果我没记错的话,主要优点是它的代码大小小于mov ax, 0
【讨论】:
mov ax, 0,但如果它产生更短的代码大小,它确实更有意义。
这正是它所做的——将寄存器的内容归零
【讨论】:
xor %ax, %ax,如前面的 cmets 所述,对应于 ax = ax xor ax。这实质上设置了 ax = 0。此外,它还影响/修改一些 EFLAGS,例如 OF、CF、SF、PF 或 ZF。在这种情况下,将设置 PF 和 ZF 标志。
SF - 指示最后一次操作的结果是否产生了最高有效位设置为 1 的值。
PF - 表示最后一次操作结果的二进制表示中设置的位数是奇数还是偶数。
ZF - 如果数学/逻辑运算的结果为零,则设置它,否则重置。
使用 GDB sn-ps 的示例如下所示。
指令:xor %ax,%ax
在“异或”之前
(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
在“异或”之后
(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
【讨论】:
mov reg, 0 不同,xor 会影响标志就足够了。由于您的回答将此问题弹出到最近活动的首页,因此我最终对一个问题发表了评论,其中包含指向更详细答案的链接,该链接说明了为什么 xor 是零规则的最佳方法。 (我提到在大多数情况下,在您想要其标志结果的指令之前进行归零。)