zoukankan      html  css  js  c++  java
  • 学 Win32 汇编[29] 串指令: MOVS*、CMPS*、SCAS*、LODS*、REP、REPE、REPNE 等


    这里的 "串" 并不单指字符串, 包括所有连续的数据(如数组); 串指令只用于内存操作.

    移动串指令: 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: 移动字符串
    ; Test29_1.asm
    .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
        szSource db 'Delphi 2010', 0 
        len      equ $ - szSource - 1
        szDest   db len dup(?), 0
    .code
    main proc
        lea esi, szSource
        lea edi, szDest
        mov ecx, len
        cld ;复位标志寄存器的方向标志, 以让串地址由低到高
        rep movsb
        PrintString szDest ;Delphi 2010
        ret
    main endp
    end main
    

    上面的例子, 假如不使用重复前缀...
    ; Test29_2.asm
    .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
        szSource db 'Delphi 2010', 0 
        len      equ $ - szSource - 1
        szDest   db len dup(?), 0
    .code
    main proc
        lea esi, szSource
        lea edi, szDest
        mov ecx, len
        cld
    @@: movsb
        dec ecx
        jnz @B
        PrintString szDest
        ret
    main endp
    end main
    

    MOVSD 例:
    ; Test29_3.asm
    .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
        ddSource dd 11h,22h,33h
        ddDest   dd lengthof ddSource dup(?)
    .code
    main proc
        lea esi, ddSource
        lea edi, ddDest
        mov ecx, lengthof ddSource
        cld
        rep movsd
        DumpMem offset ddDest, sizeof ddDest ;11 00 00 00 - 22 00 00 00 - 33 00 00 00
        ret
    main endp
    end main
    

    MOVSW 例:
    ; Test29_4.asm
    .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
        ddSource dw 11h,22h,33h
        ddDest   dw lengthof ddSource dup(?)
    .code
    main proc
        lea esi, ddSource
        lea edi, ddDest
        mov ecx, lengthof ddSource
        cld
        rep movsw
        DumpMem offset ddDest, sizeof ddDest ;11 00 22 00 - 33 00 00 00
        ret
    main endp
    end main
    

    CMPSD 例:
    ; Test29_5.asm
    .386p
    .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
        ddVal1 dd 1234h
        ddVal2 dd 5678h
    .code
    main proc
        lea esi, ddVal1
        lea edi, ddVal2
        cmpsd
        je L1
        PrintText '两数不等'
        jmp L2
    L1: PrintText '两数相等'
    L2: ret
    main endp
    end main
    

    CMPSW 例:
    ; Test29_6.asm
    .386p
    .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
        dwArr1 dw 1,2,3,4,5
        dwArr2 dw 1,3,5,7,9
    .code
    main proc
        lea esi, dwArr1
        lea edi, dwArr2
        mov ecx, lengthof dwArr1
        cld
        repe cmpsw
        je L1
        PrintText '两数组不等'
        jmp L2
    L1: PrintText '两数组相等'
    L2: ret
    main endp
    end main
    

    对比数组时, 假如数组长度不一致...
    ; Test29_7.asm
    .386p
    .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
        dwArr1 dw 1,2,3,4,5
        dwArr2 dw 1,2,3,4,5,6
    .code
    main proc
        lea esi, dwArr1
        lea edi, dwArr2
        mov ecx, lengthof dwArr1
        cmp ecx, lengthof dwArr2
        jne L1
        cld
        repe cmpsw
        jne L1
        PrintText '两数组相等'
        jmp L2
    L1: PrintText '两数组不等'
    L2: ret
    main endp
    end main
    

    如果对比的是 0 结束的字符串, 长度不一致也不用考虑
    ; Test29_8.asm
    .386p
    .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
        szText1 db 'Delphi 2010', 0
        szText2 db 'Delphi 2011', 0
    .code
    main proc
        lea esi, szText1
        lea edi, szText2
        mov ecx, lengthof szText1
        cld
        repe cmpsb
        je L1
        PrintText '字符串不同'
        jmp L2
    L1: PrintText '字符串相同'
    L2: ret
    main endp
    end main
    

    SCASB 例:
    ; Test29_9.asm
    .386p
    .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 'ABCDEFGH', 0
    .code
    main proc
        lea edi, szText
        mov al, 'F'
        mov ecx, lengthof szText - 1
        cld
        repne scasb
        je L1
        PrintText '没找到'
        jmp L2
    L1: sub ecx, lengthof szText - 1
        neg ecx
        PrintDec ecx ;如果找得到, 这里显示是第几个字符; 本例结果是 6
    L2: ret
    main endp
    end main
    

    STOSB 例:
    ; Test29_10.asm
    .386p
    .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
        len = 31
        szText db len dup(0), 0
    .code
    main proc
        lea edi, szText
        mov al, 'x'
        mov ecx, len
        cld
        rep stosb
        PrintString szText ;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        ret
    main endp
    end main
    

    LODSW 例: 数组求和
    ; Test29_11.asm
    .386p
    .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
        dwArr dw 1,2,3,4,5,6,7,8,9,10
    .code
    main proc
        lea esi, dwArr
        mov ecx, lengthof dwArr
        xor edx, edx
        xor eax, eax
    @@: lodsw
        add edx, eax
        loop @B
        PrintDec edx ;55
        ret
    main endp
    end main
    

  • 相关阅读:
    Kubernetes-Pod的扩、缩容以及滚动升级
    从一个例子开始认识Kubernetes
    Kubernetes的基本术语和概念
    一分钟看懂Docker的网络模式和跨主机通信
    监控神器:Premotheus+Grafana安装
    Linux不同服务器之间copy文件
    Oracle 存储情况查询
    Kubernetes v1.10 快速安装(只需三步)
    django 搭建一个投票类网站(二)
    django 搭建一个投票类网站(一)
  • 原文地址:https://www.cnblogs.com/del/p/1714479.html
Copyright © 2011-2022 走看看