串操作指令
串处理:rep movs/stos/lods cmps/scas
        
        
        格式: 
        REP string primitive
其中String Primitive可为MOVS, LODS或STOS指令
执行的操作:
1)如(CX)=0则退出REP ,否则往下执行。
2)(CX) <= (CX)-1
3)执行其中的串操作
4)重复1)~3)
CLD(Clear direction flag)该指令使DF=0,在执行串操作指令时可使地址自动增量;
STD(Set direction flag)该指令使DF=1,在执行串操作指令时可使地址自动减量。
        
REP MOVS BYTE PTR[DI],BYTE PTR[SI]
上面指令将[si]中的值拷贝到[di]位置,然后di和si同方向增加或者减少一个字节(由DF值决定),直到ecx中的值为0。
        
MOVS 串传送指令
格式:
MOVS DST,SRC
MOVSB(字节)
MOVSW(字)
其中第二、三种格式明确地注明是传送字节或字,第一种格式则应在操作数中表明是字还是字节操作,例如:MOVS ES:BYTE PTR[DI],DS:[SI]
执行的操作:
1)((DI)) <= ((SI))
2)字节操作:
(SI) <= (SI)+(或-)1,(DI) <=(DI)+(或-)1
当方向标志DF=0时用+,当方向标志DF=1时用-
        
        3)字操作:
        
        (SI) <= (SI)+(或-)2,(DI) 
        <= (DI)+(或-)2
当方向标志DF=0时用+,当方向标志DF=1时用-
该指令不影响条件码。
下面是通过汇编实现的字符串n个字节拷贝函数
void strncpy_asm(char *dst, char *src,size_t len)
{
_asm{
        
;mov edi,dst;
;mov esi,src;
;mov ecx,len;
        
mov edi, [ebp+8]//目标地址
mov esi, [ebp+0xc]//源地址
mov ecx,[ebp+0x10];//ecx里rep的次数
        
cld;//设置DF=0,ESI,EDI ++
rep movs byte ptr [edi],byte ptr[esi]
}
}
        
        
        
        STOS 存入串指令
格式:
STOS DST
STOSB(字节)
STOSW(字)
执行的操作:
字节操作: ((DI)) <= (AL),(DI) <= (DI)+-1
        
        字操作:   ((DI)) 
        <= (AX),(DI) 
        <= (DI)+-2
该指令把AL或AX的内容存入由(DI)指定的附加段的某单元中,并根据DF的值及数据类型修改DI的内容,当它与REP 联用时,可把AL或AX的内容存入一个长度为(CX)的缓冲区中。
        
        
        
        LODS 从串取指令
格式:
LODS SRC
LODSB
LODSW
执行的操作:
字节操作:(AL) <= ((SI)),(SI) <= (SI)+-1
        
        字操作: 
        (AX) <= ((SI)),(SI) 
        <= (SI)+-2
该指令把由(SI)指定的数据段中某单元的内容送到AL或AX中,并根据方向标志及数据类型修改SI的内容。指令允许使用段跨越前缀来指定非数据段的存储区。该指令也不影响条件码。一般说来,该指令不和REP 联用。有时缓冲区中的一串字符需要逐次取出来测试时,可使用本指令。
        
        
        lea           edi,[ebp
        
        mov         ecx,30h
        
        mov         eax,0CCCCCCCCh
        
        rep stos   dword 
        ptr es:[edi];
        
        
        上面这段代码是C中函数调用的时候,将栈上局部变量空间,统一设置为CC的汇编代码。CC就是INT 
        3指令的机器码,所以,一旦有程序出现异常,执行到栈上位置,就会被中断下来,以便发现问题。
        
        
        与REPE/REPZ和REPNZ/REPNE联合工作的CMPS和SCAS指令
        
        
        REPE/REPZ 当相等/为零时重复串操作
        
        格式:  REPE(或REPZ) 
        String Primitive
        
        其中String 
        Primitive可为CMPS或SCAS指令。
        
        执行的操作:
1)如(CX)=0或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行
2)(CX)ß(CX)-1
3)执行其后的串指令
4)重复1)~3)
        
        
        REPNE/REPNZ   当不相等/不为零时重复串操作
格式: REPNE(或REPNZ) String Primitive
其中String Primitive可为CMPS或SCAS指令
执行的操作: 除退出条件(CX==0)或ZF==1外,其他操作与REPE完全相同。
        
        
        
        CMPS  串比较指令
格式:
CMP SRC,DST
CMPSB
CMPSW
执行的操作:
1)((SI))-((DI))
2)字节操作:(SI) <= (SI)+-1,(DI) <= (DI)+-1
        
        字操作: 
        (SI) <= (SI)+-2,(DI) 
        <= (DI)+-2
指令把由(SI)指向的数据段中的一个字(或字节)与由(DI)指向的附加段中的一个字(或字节)相减,但不保存结果,只根据结果设置条件码,指令的其他特性和MOVS 指令的规定相同。
        
        
        
        SCAS 串扫描指令
格式:
SCAS DST
SCASB
SCASW
执行的操作:
字节操作:(AL)-((DI)),(DI) <= (DI)+-1
        
        字操作: 
        (AL)-((DI)),(DI) 
        <= (DI)+-2
该指令把AL(或AX)的内容与由(DI)指定的在附加段中的一个字节(或字)进行比较,并不保存结果,只根据结果置条件码。指令的其他特性和MOVS 的规定相同。
int strcmp_asm(char *s1, char *s2)
        
        {
        
        __asm{
        
        
                mov esi,s1;
        
        
                mov edi,s2;
        
        
                L1:
        
        
                lodsb;lodsb:[esi]<=al,esi=esi+1
        
        
                scasb;scasb:al-[edi],edi = edi+1
        
        
                jne L2;
        
        
                test al,al;判断esi中是否到达字符串末尾
        
        
                jne L1;
        
        
                xor eax,eax
        
        
                jmp L3;
        
        
                L2:
sbb eax,eax;
or al,1;
L3:
        
}
}

