学 Win32 汇编[22] - 逻辑运算指令: AND、OR、XOR、NOT、TEST

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
时间: 2024-10-11 03:27:18

学 Win32 汇编[22] - 逻辑运算指令: AND、OR、XOR、NOT、TEST的相关文章

二鸟学Win32 汇编——PE头文件

;代码段    .code;---------------------; 将内存偏移量RVA转换为文件偏移; lp_FileHead为文件头的起始地址; _dwRVA为给定的RVA地址;---------------------_RVAToOffset proc _lpFileHead, _dwRVA local @ret pushad mov esi, _lpFileHead assume esi:ptr IMAGE_DOS_HEADER add esi, [esi].e_lfanew ass

学 Win32 汇编[21] - 传送指令: MOV、LEA、XCHG、XLATB、XLAT、MOVZX、MOVSX

汇编指令的一般性要求: 1.两个操作数的尺寸必须一致; 2.操作数不能同为内存. MOV(Move): 最常用的数据传送指令 ;该指令不影响 EFlags ;指令格式: (其中的 r.m.i 分别表示: 寄存器.内存.立即数) MOV r/m, r/m/i ; Test21_1.asm .386 .model flat, stdcall include windows.inc include kernel32.inc include masm32.inc include debug.inc in

学 Win32 汇编[20]: 洞察标志寄存器

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 NT IOPL OF DF IF TF SF ZF AF PF CF 未使用 嵌套标志 I/O权限标志占2位 溢出标志 方向标志 中断允许标志 单步标志 符号标志 零标志 未使用 辅助标志 未使用 奇偶标志 未使用 进位标志 上表是 32 位寄存器 EFLAGS 的低 16 位. 不能直接读写 EFLAGS, 但有些方便的指令, 如:LAHF: 读取EFLAGS 低 8 位到 AH; SAHF 是 LAHF 的反向操作.

【win32汇编】0x04 第一个窗口程序

第一个win32汇编窗口程序,主要来自 win32汇编语言程序设计,然后加上了自己查阅msdn文档的一些理解,基本过程: start入口地址 --> _WinMain主函数 --> 定义一些需要用的消息实体和类实体 --> 注册窗口类 --> 建立并显示窗口 --> 消息循环 ( _ProcMain主要用于处理程序接受的消息 ) 1 ;模式定义 2 ;>>>>>>>>>>>>>>>>

算术与逻辑运算指令详解

算术与逻辑运算指令详解 前言 上一次讲解了数据传送指令,香型大家肯定对此有了一定的认识了.这些简单的汇编指令,却可以将复杂的程序井然有序的执行完毕,实在是让人惊叹. 算术与逻辑运算指令 算术逻辑运算包括很多种,各级大家应该能很快想出来,比如常见的加减乘除,与或非,左移右移等等还有一个区地址运算符,大家可能想不到,但是看完下面这一部分之后,就会觉得这个取地址运算符是个精妙的指令. 先说一下各个指令,见下图: 这里面比较特别的指令就是leal(取地址指令),其余的指令都是比较常规的算术和逻辑运算,相

win32汇编实现阶乘和斐波那契数列

win32阶乘程序 .486 ;使用486处理器.model flat,stdcall include \masm32\include\msvcrt.inc includelib \masm32\lib\msvcrt.lib .data result0 dd 1;存储最终结果 inputdata dd ?;输入的阶乘的最大值 type0 db '%d',0 data4 db '请输入阶乘最大值ddddd: ',0 data1 db '请输入阶乘最大值: ',0 data2 db '阶乘结果为:

Win32汇编开始 Hello Asm

今天开始学习Win32汇编 因为自己很多都是Windows方面 所以 接触一下Win32汇编 .386 ;.386指令集 .model flat,stdcall ;工作模式 option casemap:none ;关键字大小写不敏感 include Windows.inc include kernel32.inc includelib kernel32.lib include user32.inc includelib user32.lib .data MessageBoxText db "H

【Win32汇编】编译环境配置

开始学习[Win32汇编],编译过程较为繁琐,做个记录. 使用 MASM32 提供的 ml.exe 和 link.exe,以及 VS2013 中的 nmake.exe 和资源编辑器. ml.exe: ml  [选项]  文件列表  [/link] link.exe: link  [选项]  文件列表 nmake.exe: nmake  [选项]  [描述文件名]  [宏定义]  [目标文件] /f 描述文件名:指定其他的描述文件名,而不是默认的 makefile 宏定义:指定新的定义,覆盖描述文

谈Win32汇编

最近接触到Win32汇编,才知道汇编必须是和平台相关的,如做应用则和操作系统和CPU类型相关,而做操作系统就和只和的CPU类型有关.对于<微机原理>里面的汇编,那是DOS汇编,而Win32汇编是基于Windows的汇编.DOS和Windows是两个完全不同的操作系统了. DOS汇编功能的实现依靠的是DOS系统提供的软中断,DOS程序是面向过程的单任务的:而Win32汇编功能的实现依靠的是WinAPI,基本的元素是与具体CPU类型有关的汇编指令(一般都是X86啦,因为微软就支持这个~~).然后记