Win32汇编其他指令(4)


title: Win32汇编其他指令(4)
date: 2019-04-19 10:09:50
tags:

  • 汇编语言
    categories: 汇编语言
    copyright: true
    ---

汇编语言(assembly language)是一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言.在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数的地址.在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令,普遍地说,特定的汇编语言和特定的机器语言指令集是相互对应的,不同平台之间不可直接移植.



字串操作指令

移动串指令: MOVSB、MOVSW、MOVSD ;从 ESI -> EDI; 执行后, ESI 与 EDI 的地址移动相应的单位
比较串指令: CMPSB、CMPSW、CMPSD ;比较 ESI、EDI; 执行后, ESI 与 EDI 的地址移动相应的单位
扫描串指令: SCASB、SCASW、SCASD ;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化
储存串指令: STOSB、STOSW、STOSD ;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化
载入串指令: LODSB、LODSW、LODSD ;将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化
其中的 B、W、D 分别指 Byte、Word、DWord, 表示每次操作的数据的大小单位.

上述指令可以有重复前缀:
REP ECX > 0 时
REPE (或 REPZ) ECX > 0 且 ZF=1 时
REPNE(或 REPNZ) ECX > 0 且 ZF=0 时
;重复前缀可以自动按单位(1、2、4)递减 ECX

字符串复制(movsb):

.data
    string1 db "hello lyshark",0      ; 原始字符串
    str_len equ $ - string1 -1        ; 计算出原始字符串长度
    string2 db str_len dup(?),0       ; 目标内存地址

.code
    main PROC
        cld                       ; 清除方向标志
        mov esi,offset string1    ; 取源字符串内存地址
        mov edi,offset string2    ; 取目标字符串内存地址
        mov ecx,str_len           ; 指定循环次数,为原字符串长度
        rep movsb                 ; 逐字节复制,直到ecx=0为止
        ret
    main ENDP
END main

另一种字串复制(movsb): 不使用rep重复前缀的方式完成字串复制.

.data
    string1 db "hello lyshark",0      ; 原始字符串
    str_len equ $ - string1 -1        ; 计算出原始字符串长度
    string2 db str_len dup(?),0       ; 目标内存地址

.code
    main PROC
        lea esi,string1               ; 取string1的地址
        lea edi,string2               ; 取string2的地址
        mov ecx,str_len               ; 取字符串长度,用于循环
        cld                       ; 方向->正向
    @@: movsb                     ; 每次复制一个字节BYTE
        dec ecx                   ; 每次ecx减一
        jnz @B                    ; 如果ecx不为0则循环
        ret
    main ENDP
END main

(movsd)四字节复制字串:

.data
    ddSource DWORD 10h,20h,30h               ; 定义三个四字节数据
    ddDest   DWORD lengthof ddSource dup(?)  ; 得到目标地址

.code
    main PROC
        lea esi,ddSource
        lea edi,ddDest
        mov ecx,lengthof ddSource
        cld
        rep movsd
        ret
    main ENDP
END main

CMPSB:

.data
    Text1 db "hello lyshark",0
    Text2 db "hello lyshar1",0
.code
    main PROC
        lea esi,Text1
        lea edi,Text2
        mov ecx,lengthof Text1
        cld
        repe cmpsb
        je L1
        xor eax,eax            ; 字串不同则清空eax
        jmp L2
    L1: xor ebx,ebx            ; 字串相同则清空ebx
    L2: ret
    main ENDP
END main

CMPSD: 比对两个双字数据是否相等.

.data
    var1 DWORD 1234h
    var2 DWORD 5678h
.code
    main PROC
        lea esi,var1
        lea edi,var2
        cmpsd
        je L1
        xor eax,eax      ; 两数如果相等则清空eax
        jmp L2
    L1: xor ebx,ebx      ; 两数不相等则清空ebx
    L2: ret
    main ENDP
END main

CMPSW:

.data
    Array1 WORD 1,2,3,4,5      ; 必须全部相等才会清空ebx
    Array2 WORD 1,3,5,7,9
.code
    main PROC
        lea esi,Array1
        lea edi,Array2
        mov ecx,lengthof Array1
        
        cld
        repe cmpsw
        je L1
        xor eax,eax        ; 两数不相等则清空eax
        jmp L2
    L1: xor ebx,ebx        ; 两数相等则清空ebx
    L2: ret
    main ENDP
END main

SCASB 扫描字串: 依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化

.data
    szText BYTE "ABCDEFGHIJK",0
.code
    main PROC
    
        lea edi,szText
        mov al,"F"
        mov ecx,lengthof szText -1
        cld
        repne scasb                 ; 如果不相等则重复
        je L1
        xor eax,eax                 ; 如果没找到F则清空eax
        jmp L2
    L1: sub ecx,lengthof szText -1
        neg ecx           ; 如果找得到, 这里显示是第几个字符; 本例结果是 6
    L2: ret
    main ENDP
END main

STOSB 存储字串: 将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化

.data
    len = 10
    szText db len dup(0),0
.code
    main PROC
        lea edi,szText                   ; EDI指向字符串
        mov al,"W"                       ; 定义查找字母为W
        mov ecx,len                      ; 设置查找计数器
        cld                              ; 方向=正向
        rep stosb                        ; ecx>0则执行
        ret
    main ENDP
END main

LODSW 载入指令: 将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化,如下是累加求和

.data
    Array WORD 1,2,3,4,5,6,7,8,9,10
.code
    main PROC
        lea esi,Array
        mov ecx,lengthof Array
        xor edx,edx
        xor eax,eax
    @@: lodsw
        add edx,eax
        loop @B
        
        mov eax,edx           ; 最后将相加结果放入eax

    main ENDP
END main

初始化内存: 把String字符串中的,每一个字节均填充初始化为0FFh

.data
    Count = 100                 ; 申请空间为100
    String BYTE Count DUP(?)    ; 初始化为BYTE
.code
    main PROC
        mov al,0FFh             ; 指定要填充的数据为0FFh
        mov edi,offset String   ; EDI寄存器指向目标内存
        mov ecx,Count           ; 循环计数
        cld                     ; 初始化:方向=前方
        rep stosb               ; 以AL中的值进行填充
        ret
    main ENDP
END main

数组的乘法: 把双字数组中的每一个元素分别乘以一个常量,程序中使用了(LODSD加载),(STOSD保存).

.data
    Array DWORD 1,2,3,4,5
    Multi DWORD 10
.code
    main PROC
        mov esi,offset Array     ; 源指针
        mov edi,esi              ; 目的指针
        
        cld                      ; 方向=向前
        mov ecx,lengthof Array   ; 循环计数器
    L1: lodsd                    ; 加载[esi]至EAX
        mul Multi                ; 将EAX乘以10
        stosd                    ; 将结果从EAX存储至[EDI]
        loop L1
        ret
    main ENDP
END main

计算字符串长度: 以下代码用于计算字符串的长度,并将结果保存在EAX寄存器中.

.data
    String BYTE "hello world",0      ; 带计算字符串
.code
    main PROC
        mov edi,offset String    ; 取出字符串的基地址
        xor eax,eax              ; 清空eax用作计数器
        
    L1: cmp byte ptr [edi],0     ; 分别那[edi]的值和0作比较
        je L2                    ; 上一步为零则跳转得到ret
        inc edi                  ; 否则继续执行
        inc eax
        jmp L1
    L2: ret
    
    main ENDP
END main

小写字串转大写: 将MyString变量中的小写字符串,依次转换为大写字符串.

.data
    MyString db "hello lyshark",0      ; 定义MyString字符串

.code
    main PROC
        mov esi,offset MyString        ; 取出字符串的偏移地址
    L1: cmp byte ptr [esi],0           ; 分别拿出每一个字节,与0比较
        je L2                          ; 如果相等则跳转到L2
        and byte ptr [esi],11011111b   ; 执行按位与操作
        inc esi                        ; 每次esi指针递增1
        jmp L1                         ; 重复循环
    L2: ret
    main ENDP
END main

定义二维数组: 定义一个二维数组Table,并取出第一行中的第2偏移地址的元素.

.data
    Table WORD 10h,20h,30h,40h,50h    ; 定义一个数组
    Row = ($ - Table)                 ; 取出数组每行的字节数
          WORD 60h,70h,80h,90h,0Ah    ; 继续定义数组
.code
    main PROC
        row_index = 1                 ; 表的偏移地址
        column_index = 2              ; 行的偏移地址
        
        mov ebx,offset Table          ; 取偏移地址给ebx
        add ebx,Row*row_index         ; 每行元素*偏移
        
        mov esi,column_index          ; 将行偏移赋值给esi
        mov ax,[ebx+esi*TYPE Table]   ; Table比例因子只能是2,4,8
    main ENDP
END main


位操作指令

符号扩展(CBW/CWDE):

.code
    main PROC
        mov al,7fh
        cbw                 ; 将 AL 扩展为 AX
        PrintHex ax ;007F
        mov al,80h
        cbw
        PrintHex ax ;FF80
        
        mov ax,7fffh
        cwde                 ; 将 AX 扩展为 EAX
        PrintHex eax
    main ENDP
END main

符号扩展(CDQ/CWD):

.code
    main PROC
        mov eax,7FFFFFFFh
        cdq                      ; 将 EAX 扩展为 64 位数 EDX:EAX
        PrintHex edx ;00000000
        PrintHex eax ;7FFFFFFF
        
        mov ax, 7FFFh
        cwd                       ; 将 AX 扩展为 DX:AX
        PrintHex dx ;0000
        PrintHex ax ;7FFF
        
    main ENDP
END main

BT、BTS、BTR、BTC: 位测试指令

;BT(Bit Test): 位测试
;BTS(Bit Test and Set): 位测试并置位
;BTR(Bit Test and Reset): 位测试并复位
;BTC(Bit Test and Complement): 位测试并取反

;它们的结果影响 CF
;它们的指令格式相同:
BT r16/r32/m16/m32, r16/r32/m16/m32
BT r16/r32/m16/m32, i8

.code
main proc
    ;BT 把 10000001b 的第七位复制到 CF, 得知是 1
    mov dx, 10000001b
    bt  dx, 7
    lahf
    PrintHex ah ;47 - 01000111b (CF=1)
    ;BT 把 10000001b 的第六位复制到 CF, 得知是 0
    bt  dx, 6
    lahf
    PrintHex ah ;86 - 10000110b (CF=0)
    
    ;BTS 在执行 BT 命令的同时, 把操作数的指定位置为 1
    mov dx, 10000001b
    bts dx, 6
    PrintHex dl ;C1 - 11000001b
    
    ;BTR 在执行 BT 命令的同时, 把操作数的指定位置为 0
    mov dx, 10000001b
    btr dx, 7
    PrintHex dl ;01 - 00000001b
    
    ;BTC 在执行 BT 命令的同时, 把操作数的指定位取反
    mov dx, 10000001b
    btc dx, 0
    PrintHex dl ;80 - 10000000b
    btc dx, 0
    PrintHex dl ;81 - 10000001b
    ret
main endp
end main

BSF、BSR: 位扫描指令

;BSF(Bit Scan Forward): 位扫描, 低 -> 高
;BSR(Bit Scan Reverse): 位扫描, 高 -> 低

;它们的结果影响 ZF

;扫描的是参数二, 找到是 1 的位后, 把位置数给参数一并置 ZF=0
;找不到(也就是参数二是 0)时, 置 ZF=1

;它们的指令格式相同:
BSF r16/r32, r16/r32/m16/m32

.code
main proc
    ;扫描到时
    mov dx, 0000111100001100b
    bsf cx, dx
    PrintDec cx ;2  - 也就是左数第 3 位
    
    bsr cx, dx
    PrintDec cx ;11 - 也就是左数第 12 位
    
    ;扫描不到时
    mov cx, 0FFFFh
    mov dx, 0
    bsf cx, dx
    lahf
    PrintHex ah ;C6 - 11000110 (ZF=1)
    PrintHex cx ;FFFF - 找不到时不会影响到目的值
    ret
main endp
end main

其他测试指令

转载于:https://www.cnblogs.com/LyShark/p/11136331.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值