串操作指令

  串操作指令可以方便对一组连续的数据进行操作。串操作后自动根据DF标志位修改ESI和EDI,DF = 0时,ESI,EDI递增,DF = 1时,ESI,EDI递减。串操作指令有2组,1组实现数据串传送,另1组实现数据串检测。串操作指令通常需要反复执行,所以常与重复指令前缀联合使用,它通过计数器ECX控制重复执行串指令的次数。

1.串传送指令

这组指令实现对串的传送,它们有,MOVS,STOS,LODS,可以配合REP前缀,但不影响标志。

MOVSB      ;BYTE PTR[EDI] = BYTE PTR[ESI]

MOVSW      ;WORD PTR[EDI] = WORD PTR[ESI]

MOVSD      ;DWORD PTR[EDI] = DWORD PTR[EDI]

STOSB      ;BYTE PTR[EDI] = AL

STOSW      ;WORD PTR[EDI] = AX

STOSD      ;DWORD PTR[EDI] = EAX

LODSB      ;AL = BYTE PTR[ESI]

LODSW      ;AX = WORD PTR[ESI]

LODSD      ;EAX = DWORD PTR[ESI]

REP重复指令前缀,可以表示为当ECX != 0时,则继续执行,直到ECX = 0。可以说,ECX指明了重复次数。如果不使用REP前缀,那么串指令其实是只被执行1次的,这是很多新手易出错的地方。

比如,我们可以使用串传送指令代替ZeroMemory。

结合上篇文章,我们可以定义一个宏,程序源码如下:

ZeroMem        MACRO    Addr,Size
    cld    ;;CLD标志位清0,表示递增正向传输
    xor    al,al
    mov    edi,Addr
    mov    ecx,Size
    rep    stosb
endm

调用格式如下:

ZeroMem 数据串地址,长度

2.串检测指令

这组指令包含有CMPS和SCAS。由于串比较指令和减法的实质是一样的,所以它们也影响标志位。这两个串操作指令可以和REPE/REPZ和REPNE/REPNZ联合使用,通过ZF判断是否相等。

CMPSB      ;BYTE PTR[ESI] - BYTE PTR[EDI]

CMPSW      ;WORD PTR[ESI] - WORD PTR[EDI]

CMPSD      ;DWORD PTR[ESI] - DWORD PTR[EDI]

SCASB      ;AL - BYTE PTR[EDI]

SCASW      ;AX - WORD PTR[EDI]

SCASD      ;EAX - DWORD PTR[EDI]

REPE/REPZ    ;每执行一次指令,ECX递减1。如果ECX = 0或ZF = 0,则结束重复执行

REPNE/REPNZ   ;每执行一次指令,ECX递减1。如果ECX = 0或ZF = 1,则结束重复执行

实际运用时要注意区分,串操作指令结束时因为比较完了,还是因为标志位问题。

我根据串操作指令定义了一个宏,可以代替ComapreMemory,如下:

CmpMem        MACRO    Addr1,Addr2,Size
    LOCAL    n
    xor    eax,eax
    mov    esi,Addr1
    mov    edi,Addr2
    mov    ecx,Size
    repe    cmpsb    ;;当ZF = 0时,结束是因为有不同
    jnz    n    ;;当两数据串完全相等时,则EAX = 1
    inc    eax
n:
endm

 

原文地址:https://www.cnblogs.com/galano/p/8721794.html