逻辑与(And)

两个数进行And运算时,当两个位都是1时,那么结果为1,否则为0,举例8 And 10,8的二进制是1000,10的二进制是1010,所以最后的结果为8(1000)。

1000  (8)
1010  (10)
1000  (8)

受影响的标志位有CF、OF、PF、SF、ZF。

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
.data
szMessage db 'a',10,13,0
bTest1 dword -1
szPause db 'pause',10,13,0
szOutFmt byte '%d and %d =%d',10,13,0
.code

x dword 5
START:
mov eax,8
and eax,10
invoke printf,addr szOutFmt,8,10,eax
invoke system ,addr szPause
END START

Win32汇编系列四、逻辑运算指令_java

逻辑或(OR)

当两个数进行OR运算时,只要有一个为1的,那么就是1,否则为0,如8 OR 10,结果为。

1000  (8)
1010  (10)
1010   (10)

受影响的标志位CF、OF、PF、SF、ZF

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
.data
szMessage db 'a',10,13,0
bTest1 dword -1
szPause db 'pause',10,13,0
szOutFmt byte '%d or %d =%d',10,13,0
.code

x dword 5
START:
mov eax,8
or eax,10
invoke printf,addr szOutFmt,8,10,eax
invoke system ,addr szPause
END START


逻辑非(NOT)

取反,也就是0变成1,1变0,如NOT 8 为-9,怎么等于-9了呢?别忘了是32位的二进制,他前面的0都会变成1,最后的二进制是11111111111111111111111111110111,这个表示-9。要理解这个,就得回到补码、反码、源码的知识了。

1000
0111
-9
.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
.data
szMessage db 'a',10,13,0
bTest1 dword -1
szPause db 'pause',10,13,0
szOutFmt byte 'not %d  =%d',10,13,0
.code

x dword 5
START:
mov eax,8
not eax
invoke printf,addr szOutFmt,8,eax
invoke system ,addr szPause
END START

Win32汇编系列四、逻辑运算指令_java_02

逻辑异或(XOR)

运算规则是:0 XOR 0=0、
0 XOR 1=1、 1 XOR 0=1、 1 XOR 1=0

也就是如果两个相应位的值不同,则结果为1,否则为0,在看8 XOR 10,结果为2。

1000
1010
0010
.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
.data
szMessage db 'a',10,13,0
bTest1 dword -1
szPause db 'pause',10,13,0
szOutFmt byte '%d xor %d =%d',10,13,0
.code

x dword 5
START:
mov eax,8
xor eax,10
invoke printf,addr szOutFmt,8,10,eax
invoke system ,addr szPause
END START

Win32汇编系列四、逻辑运算指令_java_03

逻辑比较测试TEST

TEST指令的功能是源操作数中的每位二进制数与目的操作数中的相应二进制数进行逻辑与运算,但结果不存入目的操作数中,通常后面会紧跟着JZ、JNZ等条件转移指令,JZ就是ZF标志等于1的时候跳转,JNZ则在ZF标志等于0时候跳转,ZF标志反映了运算结果是否为0,如果为0,则ZF位为1,否则为0。

(对于这一条,我不太确定,因为很多文章、博客中说的和我实践的相反,也或许我有什么错误)

结果=0       ZF=1
结果!=0      ZF=0

受影响的标志位CF、OF、PF、SF、ZF。

测试一组数据:

8 AND 7结果=0,那么ZF位=1,使用JNZ则不跳转。

8 AND 8结果=8,那么ZF位=0,使用JNZ跳转。

.386
.Model Flat, StdCall
Option Casemap :None

include C:\masm32\include\kernel32.inc
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\msvcrt.lib


printf    PROTO C : dword,:vararg
system   PROTO C : dword,:vararg
.data
szMessage db 'a',10,13,0
bTest1 dword -1
szPause db 'pause',10,13,0
szOutFmt1 byte '未跳转',10,13,0
szOutFmt2 byte '跳转',10,13,0
.code

x dword 5
START:
mov eax,8
test eax,8
jnz Exit
invoke printf,addr szOutFmt1
invoke system ,addr szPause
Exit:
invoke printf,addr szOutFmt2
invoke system ,addr szPause
END START

运行之后发现跳转执行了,如果 test eax,7,则不会发生跳转。Win32汇编系列四、逻辑运算指令_java_04

真TM的绕。