1. 程式人生 > >學 Win32 匯編[22] - 邏輯運算指令: AND、OR、XOR、NOT、TEST

學 Win32 匯編[22] - 邏輯運算指令: AND、OR、XOR、NOT、TEST

xor 原來 .lib 標誌位 cal loop win text model

AND: 邏輯與


;該指令會置 CF=OF=0; 其結果影響 SF、ZF、PF
;指令格式:
AND r/m, r/m/i


; Test22_1.asm - 使用 AND 運算將一個數的第二、四位清零
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
main proc
mov al, 00001111b and al, 11110101b PrintHex al ;05 - 00000101b ret main endp end main


; Test22_2.asm - 使用 AND 運算將字母轉大寫
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib
debug.lib .data szText db ‘Delphi‘, 0 .code main proc lea esi, szText mov ecx, lengthof szText - 1 @@: and byte ptr [esi], 11011111b ;大寫字母和小寫字母只有第五位不同 inc esi loop @B PrintString szText ;DELPHI ret main endp end main


OR: 邏輯或


;該指令會置 CF=OF=0; 其結果影響 SF、ZF、PF
;指令格式:
OR r/m, r/m/i


; Test22_3.asm - 使用 OR 運算確保一個數的第二、四位是 1
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
main proc
    mov al, 11110001b
    or  al, 00001010b 
    PrintHex al ;FB - 11111011b
    ret
main endp
end main


; Test22_4.asm - 使用 OR 運算將字母轉小寫
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
    szText db ‘Delphi‘, 0
.code
main proc
    lea esi, szText
    mov ecx, lengthof szText - 1
@@: or byte ptr [esi], 00100000b ;大寫字母和小寫字母只有第五位不同
    inc esi
    loop @B
    PrintString szText ;delphi
    ret
main endp
end main


XOR: 邏輯異或


;該指令會置 CF=OF=0; 其結果影響 SF、ZF、PF
;指令格式:
XOR r/m, r/m/i


; Test22_5.asm - 兩次和一個相同的數 XOR 恢復到原來的數
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
main proc
    mov eax, 12345
    xor eax, 88888888
    PrintDec eax      ;88892929
    xor eax, 88888888
    PrintDec eax      ;12345
    ret
main endp
end main


; Test22_6.asm - 使用 XOR 加密與解密字符串
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
    szText db ‘Hello World!‘, 0
.code
main proc
    ;加密
    lea esi, szText
    mov ecx, lengthof szText - 1
@@: xor byte ptr [esi], 123 ;使用 123 做密碼
    inc esi
    loop @B
    PrintString szText      ;顯示亂碼
    
    ;解密
    lea esi, szText
    mov ecx, lengthof szText - 1
@@: xor byte ptr [esi], 123
    inc esi
    loop @B
    PrintString szText      ;Hello World!
    ret
main endp
end main


NOT: 邏輯取反


;該指令不影響 EFlags
;指令格式:
NOT r/m


; Test22_7.asm - 使用 NOT 加密與解密字符串
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
    szText db ‘Hello World!‘, 0
.code
main proc
    ;加密
    lea esi, szText
    mov ecx, lengthof szText - 1
@@: not byte ptr [esi]
    inc esi
    loop @B
    PrintString szText  ;顯示亂碼
    
    ;解密
    lea esi, szText
    mov ecx, lengthof szText - 1
@@: not byte ptr [esi]
    inc esi
    loop @B
    PrintString szText  ;Hello World!
    ret
main endp
end main


TEST: 測試邏輯與


;該指令會置 CF=OF=0; 其結果影響 SF、ZF、PF
;指令格式:
TEST r/m, r/m/i

;TEST 同 AND, 但它不修改運算數, 只改變標誌寄存器; 也就是嘗試 AND 的結果
;常用到它對 ZF 的影響(結果為0時ZF=1)
;TEST 之後常常跟著條件跳轉指令 JZ、JNZ


; Test22_8.asm - 觀察 TEST 之後的零標誌位(ZF)
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.code
main proc
    ;判斷字母 A 二進制(01000001)的其最後一位是否是 0, 如果是 0 那麽 ZF=1
    mov  al, ‘A‘
    test al, 00000001b
    lahf
    PrintHex ah ;02 - 00000010b (ZF=0)
    
    ;判斷字母 B 二進制(01000010)的其最後一位是否是 0, 如果是 0 那麽 ZF=1
    mov  al, ‘B‘
    test al, 00000001b
    lahf
    PrintHex ah ;46 - 01000110b (ZF=1)
    
    ;判斷 ecx 是否為空
    mov ecx, 1
    test ecx, ecx
    lahf
    PrintHex ah ;06 - 00000010b (ZF=0, 不為空)
    
    xor  ecx, ecx
    test ecx, ecx
    lahf
    PrintHex ah ;06 - 01000110b (ZF=1, 為空)
    ret
main endp
end main


; Test22_9.asm - 判斷字符串中每個字符的二進制位的最後一位是 1 還是 0
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
    szText db ‘Delphi‘, 0
.code
main proc
    ;清空兩個寄存器用於計數
    xor eax, eax
    xor edx, edx
    
    lea esi, szText                 ;字符串地址
    mov ecx, lengthof szText - 1    ;字符串長度
L1: test byte ptr [esi], 00000001b  ;循環測試每個字符的最後一位是 1 還是 0
    jz L2    ;如果是 0 則跳到 L2 給 edx+1
    inc eax  ;反之給 eax+1
    jmp L3
L2: inc edx
L3: inc esi
    loop L1
    
    PrintDec eax ;2 - 這是最後一位是 1 的字符的個數: e、i
    PrintDec edx ;4 - 這是最後一位是 0 的字符的個數: D、l、p、h
    ret
main endp
end main

學 Win32 匯編[22] - 邏輯運算指令: AND、OR、XOR、NOT、TEST