现在的位置: 首页 > 综合 > 正文

Win32ASM学习[18]:串指令-MOVS*、CMPS*、SCAS*、LODS*、REP、REPE、REPNE

2013年02月08日 ⁄ 综合 ⁄ 共 5220字 ⁄ 字号 评论关闭

--------------------------------------------------------------------------------------------------------------------------------------------------------

一.字符串传送指令  MOVSB/MOVSW/MOVSD

 格式: MOVS OPD,OPS 
 功能: OPD<--OPS.

 

说明: 1. 其中OPS为源串符号地址,OPD为目的串符号地址.
          2. 对字节串操作时: 若DF=0,则作加,即[ES:DI]<--[DS:SI],(SI)<--(SI)+1,(DI)<--(DI)+1.
                          若DF=1,则作减,即 (SI)<--(SI)-1,(DI)<--(DI)-1.
          3. 对字串操作时: 若DF=0,则作加,即(SI)<--(SI)+2,(DI)<--(DI)+2.
                        若DF=1,则作减,即(SI)<--(SI)-2,(DI)<--(DI)-2.

          4. 在指令中不出现操作数时,字节串传送格式为MOVSB、字串传送格式为MOVSW,双            字传送格式为MOVSD

          5. 本指令不影响标志位.

          6. 例如: 将存储器中变量A开始的200个数据串传送至B开始的存储区,可用以下程            序段实现:
                MOV SI,OFFSET A ;SI指向源串首址
                MOV DI,OFFSET B ;DI指向目的串首址
                MOV CX,200         ;字节串或字串长度200送CX
                CLD                       ;0-->DF 
      ATOB:MOVS B,A   ;对字节串传送可用MOVSB
                DEC CX                 ;(CX)<--(CX)-1 
                JNZ ATOB             ; 
                (CX)<>0,转至ATOB

         7. 用指令MOVS?   B,A究竟是字节传送,还是字传送,取决于A,B的类型定义.
                 若DF=0,则在字传送时,(SI)<--(SI)+2,(DI)<--(DI)+2.

----------------------------------------------------------------------------------------------------------------------------------------------------------

.

二.比较串指令:CMPSBCMPSWCMPSD
;比较 ESI、EDI; 执行后, ESI 与 EDI 的地址移动相应的单位

 

字符串比较指令

 格式: CMPS      OPRD1,OPRD2
 ----  CMPSB
         CMPSW

 功能: 由SI寻址的源串中数据与由DI寻址的目的串中数据进行比较,比较结果送标志位,而
 ----  不改变操作数本身.同时SI,DI将自动调整.

 

说明: 1. 其中OPRD2为源串符号地址,OPRD1为目的串符号地址.
        2. 本指令影响标志位AF、CF、OF、SF、PF、ZF.本指令可用来检查二个字符串是否相同,可以使用循环控制方法对整串进行比较.

        3. 与MOVS相似,CMPS指令也可以不使用操作数,此时可用指令CMPSB或CMPSW分别表示字节串比较或字串比较.

        4. 例如: 对两个字节串进行比较,若一致,则AL内容置为0;若不一致,则AL内容置为0FFH.程序段如下:
                MOV SI,OFFSET ST1
                MOV DI,OFFSET ST2 
                MOV CX,N
                CLD 
       NEXT:CMPSB
                JNZ FIN
                DEC CX
                JNZ NEXT
                MOV AL,0
                JMP OVR

         FIN:MOV AL,0FFH 
        OVR:MOV RSLT,AL

        5.CMPSD不大一样,它是双字扫描,其它的基本相同.

----------------------------------------------------------------------------------------------------------------------------------------------------------

.

三.扫描串指令:SCASBSCASWSCASD
;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化

 字符串搜索指令

 格式: SCAS OPRD
 ----  SCASB 
         SCASW

         SCASD        ;它是双字扫描,其它的基本相同

 功能: 把AL(字节串)或AX(字串)的内容与由DI寄存器寻址的目的串中的数据相减,结果置标志位,但不改变任一操作数本身.地址指针DI自动调整.
 

 说明: 1. 其中OPRD为目的串符号地址.
 ----
       2. 本指令影响标志AF、CF、OF、PF、SF、ZF.该指令可查找字符串中的一个关键字,只需在本指令执行前,把关键字放在AL(字节)或AX(字串 )中,用重复前缀可在整串中查找.
          指令中不使用操作数时,可用指令格式SCASB,SCASW,分别表示字节串或字串搜索指令.

       3. 例如: 寻找字符串中有否'$'字符
                MOV DI,OFFSET STR
                MOV CX,N               ;N为串长度
                MOV AL,'$'
                CLD 
       AGN:SCASB
                JZ FIN
                DEC CX
                JNZ AGN
                MOV AL,0 ;未找到,AL中置0
                JMP OVR 
         FIN:MOV AL,0FFH   ;找到,AL中置为0FFH 
       OVR:MOV RALT,AL

----------------------------------------------------------------------------------------------------------------------------------------------------------

.

四.储存串指令:STOSBSTOSWSTOSD
;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化

 

 字符串存储指令 STOS

 格式: STOS OPRD
 ----  STOSW

         STOSD   它是双字传送,其它的基本相同.

 功能: 把AL(字节)或AX(字)中的数据存储到DI为目的串地址指针所寻址的存储器单元中去.指针DI将根据DF的值进行自动调整.

 说明: 1. 其中OPRD为目的串符号地址.
         2. 本指令不影响标志位.当不使用操作数时,可用STOSB或STOSW分别表示字节串或字串的操作.

---------------------------------------------------------------------------------------------------------------------------------------------------------

.

五.载入串指令:LODSBLODSWLODSD
;将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化

 

 取字符串元素指令 LODS

 格式: LODS OPRD 其中OPRD为源字符串符号地址.
 
 功能: 把SI寻址的源串的数据字节送AL或数据字送AX中去, 并根据DF的值修改地址指针SI
            进行自动调整.

 

 说明:   1. 本指令不影响标志位.
           2. 当不使用操作数时,可用LODS(字节串)或LODSW(字串)指令.

----------------------------------------------------------------------------------------------------------------------------------------------------------.

上述指令可以有重复前缀

:REP 
    ECX
> 0

REPE
(或 REPZ)ECX
> 0
且 ZF=1

REPNE(或REPNZ)ECX
> 0
且 ZF=0

;重复前缀可以自动按单位(1、2、4)递减 ECX

 

嗯   串传送指令   功能都是比较强大的  

对一个函数进行反编译  我们也会发现   编译器利用了这些串传送指令 对局部变量进行了初始化  

 

xor eax,eax                     ;要将这块内存的每个单元要初始化的数值 送入eax
mov edi,offset szString   ;获取这块内存的地址 送去edi
mov ecx,dwStingSize      ;这块内存的要初始化的长度 送去ecx
cld                                  ;CLD使DF复位,即DF=0
rep stosb                        ;重复覆盖掉edi所指向的单元
REP                                ;CX<>0 重复执行字符串指令


汇编指令stosb,stosw,stosd,分别是把AL,AX,EAX的内容存储到EDI所指的内存单元中,同时根据EDI的值根据方向标志增加或减少,可配合指令REP一起使用

另外:汇编指令MOVSB,MOVSW,意思是搬移一个字节或一个字,它是把 DS:SI 所指地址的一个字节搬移到 ESI 所指的地址上,搬移后原来的内容不变,但是原来 ESI 所指的内容会被覆盖而且在搬移之后 SI 和 DI 会自动的指向下一个要搬移的地址。

RtlMoveMemory      移动内存 ----> ?--->movsb
RtlFillMemory           填充内存块 --->eax = ? ---->stosb
RtlZeroMemory        以0填充内存块 -->eax = 0 ----->stosb 如果是sw,sd的话 那样计数的方式就不一样了

---------------------------------------------------------------------------------------------------------------------------------------------------------- 

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------- 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------- 

 

 

 

 

---------------------------------------------------------------------------------------------------------------------------------------------------------- 

 

抱歉!评论已关闭.