Intel指令包含了AND,OR,XOR,NOT,TEST指令,它们能直接在二进制位上实现布尔操作。其中TEST是不会改变数据的AND指令,但会改变CPU标志位。

部分布尔指令

说明

AND

AND 指令在两个操作数的对应位之间进行按位逻辑与操作,并将结果存放在目标操作数中。操作数可以是 8、16、32、64位,但是两个操作数必须是同样大小。

OR

OR 指令在两个操作数的对应位之间进行按位逻辑或操作,并将结果存放在目标操作数中。操作数可以是 8、16、32、64位,但是两个操作数必须是同样大小。

XOR

XOR 指令在两个操作数的对应位之间进行按位逻辑异或操作,并将结果存放在目标操作数中。

NOT

翻转操作数中的所有位。其结果被称为反码。

TEST

在两个操作数的对应位之间进行 AND 操作,并根据运算结果设置符号标志位、零标志位和奇偶标志位。但是TEST 指令不修改目标操作数。

AND指令

AND指令说明

X

Y

and的结果

备注

0

0

0

0 0 得 0

0

1

0

0 1 得 0

1

0

0

1 0 得 0

1

1

1

1 1 得 1

下列是被允许的操作数组合,但是立即操作数不能超过 32 位:

AND 寄存器,寄存器
AND 寄存器,内存地址
AND 寄存器,立即数(最大32位)

AND 内存地址,寄存器
AND 内存地址,立即数(最大32位)

AND 指令可以清除一个操作数中的 1 个位或多个位,同时又不影响其他位。这个技术就称为位屏蔽,就像在粉刷房子时,用遮盖胶带把不用粉刷的地方(如窗户)盖起来。目标数的哪个位想要设计为0,操作数的对应位就写0然后其它位写1

mov al, 10101110b
and al, 11110110b    ;AL 中的结果 = 1010 0110

AND 指令提供了一种简单的方法将字符从小写转换为大写。如果对比大写 A 和小写 a 的 ASCII 码,就会发现只有第5位不同:

0  1  1  0  0  0  0  1 = 61h ('a')
0  1  0  0  0  0  0  1 = 41h ('A')

其他的字母字符也是同样的关系。下例中,数组中所有字符都转换为大写:

.data
array BYTE 50 DUP(?)

.code
    mov ecx,LENGTHOF array
    mov esi,OFFSET array
L1: and BYTE PTR [esi], 11011111b       ;清除位 5
    inc esi
    loop L1

AND 指令总是清除溢出和进位标志位,并根据目标操作数的值来修改符号标志位、零标志位和奇偶标志位。比如,下面指令的结果存放在 EAX 寄存器,假设其值为 0。在这种情况下,零标志位就会置 1:

and eax,1Fh

OR指令

OR指令说明

X

Y

or的结果

备注

0

0

0

0 0 得 0

0

1

1

0 1 得 1

1

0

1

1 0 得 1

1

1

1

1 1 得 1

下列是被允许的操作数组合,但是立即操作数不能超过 32 位。

OR 寄存器,寄存器
OR 寄存器,内存地址
OR 寄存器,立即数
OR 内存地址,寄存器
OR 内存地址,立即数

当需要在不影响其他位的情况下,将操作数中的 1 个位或多个位置为 1 时,OR 指令就非常有用了。目标数哪个位要改为1,就把操作数对应的位置改为1然后其它位写0。如果 AL 初始化为二进制数 1110 0011,把它与 0000 0100 进行 OR 操作,其结果等于 1110 0111:

mov al,11100011b
or al, 00000100b        ;AL 中的结果 =1110 0111

OR 指令总是清除进位和溢出标志位,并根据目标操作数的值来修改符号标志位、零标志位和奇偶标志位。比如,可以将一个数与它自身(或 0)进行 OR 运算,来获取该数值的某些信息:

or al,al

零标志位

符号标志位

AL 中的值

清0

清0

大于0

置1

清0

等于0

清0

置1

小于0

XOR指令

XOR 指令操作数组合和大小与 AND 指令及 OR 指令相同。两个操作数的每一对对应位都应用如下操作原则:如果两个位的值相同(同为 0 或同为 1),则结果位等于 0;否则结果位等于 1。

x

y

XOR结果

备注

0

0

0

0 0 得 0

0

1

1

0 1 得 1

1

0

1

1 0 得 1

1

1

0

1 1 得 0

对相同操作数进行两次 XOR 运算,则结果逆转为其本身。如下表所示,位 x 与位 y 进行了两次异或,结果逆转回 x 的初始值。异或运算这种“可逆的”属性使其成为简单对称加密的理想工具

x

y

x㊉y(第一次XOR)

(x㊉y)㊉y(第二次XOR)

0

0

0

0

0

1

1

0

1

0

1

1

1

1

0

1

XOR 指令总是清除溢岀和进位标志位,并根据目标操作数的值来修改符号标志位、零标志位和奇偶标志位。

NOT指令

NOT 指令触发(翻转)操作数中的所有位,其结果被称为反码。0变成1,1变成0。该指令允许的操作数类型如下所示:

NOT 寄存器

NOT 内存地址

例如,F0h 的反码是 0Fh:

mov al,11110000b
not al           ;AL = 00001111b

NOT 指令不影响标志位。

TEST指令

TEST 与 AND 指令唯一不同的地方是,TEST 指令不修改目标操作数。TEST 指令允许的操作数组合与 AND 指令相同。在发现操作数中单个位是否置位时,TEST 指令非常有用。TEST 指令同时能够检查几个位。假设想要知道 AL 寄存器的位 0 和位 3 是否置 1,可以使用如下指令:

test al, 00001001b    ;测试位 0 和位 3

从下面的数据集例子中,可以推断只有当所有测试位都清 0 时,零标志位才置 1:

 0  0  1  0  0  1  0  1    <- 输入值
0  0  0  0  1  0  0  1    <- 测试值
0  0  0  0  0  0  0  1    <- 结果:ZF=0

0  0  1  0  0  1  0  0    <- 输入值
0  0  0  0  1  0  0  1    <- 测试值
0  0  0  0  0  0  0  0    <- 结果:ZF=1

TEST 指令总是清除溢出和进位标志位,其修改符号标志位、零标志位和奇偶标志位的方法与 AND 指令相同。