汇编语言第4章王爽版程序设计(字符串).ppt
第4章汇编语言程序设计,一、概述二、顺序程序设计三、DOS系统功能调用四、分支程序设计五、循环程序设计六、串处理类指令及程序设计,六、数据串处理指令,串传送指令(MOVS)ES:DIDS:SI串读取指令(LODS)AL/AXDS:SI3.串存储指令(STOS)ES:DIAL/AX4.串比较指令(CMPS)DS:SIES:DI5.串扫描指令(SCAS)AL/AXES:DI6.重复前缀指令(REP、REPZ、REPNZ),计算机更多的是要进行一些数据处理,主要的是字符串的处理。,熟悉串操作寻址的特点,串操作指令概括说明,为什么要用:数据传送类指令每次只能传送一个数据,若要传送大批数据就需要重复编程(通过循环来实现),这样就浪费了大量的时间和空间。为此8086提供了一组处理内存中连续存放数据的串指令,这就是串操作指令。,串操作指令是8086指令系统中比较独特的一类指令,采用比较特殊的数据串寻址方式,是可以直接实现存储区之间操作的指令。在操作内存连续区域的数据时,特别好用。,串操作指令的操作对象(操作数)是内存中连续存放的数据串(String)即在连续的内存区域中以字(W)为单位的字串,或是以字节(B)为单位的字节串,串寻址方式,名称:“S”、“B”、“W”格式:提供3种格式,常用的有2种。隐含的都是双操作数指令源操作数用寄存器SI寻址,默认在数据段DS中,DS:SI,但允许段超越目的操作数用寄存器DI寻址,默认在附加段ES中,ES:DI,不允许段超越每执行一次串操作指令,SI和DI值将自动修改:1(对于字节串)或2(对于字串)执行指令CLD指令后,DF=0,地址指针增1或2执行指令STD指令后,DF=1,地址指针减1或2,串操作类指令,1.串传送指令*(MOVS)2.串读取指令*(LODS)3.串存储指令*(STOS)4.串比较指令(CMPS)5.串扫描指令(SCAS)6.重复前缀指令(REP*、REPZ、REPNZ),串传送MOVS,功能:将以SI为指针的源串中的一个字节(或字)存储单元中的数据传送至以DI为指针的目的地址中去,并自动修改指针,使之指向下一个字节(或字)存储单元。即:DS:SIES:DI。当DF=0时,SI和DI自动增量;当DF=1时,SI和DI自动减量。,MOVSB;字节串传送:ES:DIDS:SI;SISI1,DIDI1,演示,MOVSW;字串传送:ES:DIDS:SI;SISI2,DIDI2,演示,特殊性?,内存操作数之间直接传送,例1:字节串传送,mov si,offset sourcemov di,offset destinationmov cx,100;cx传送次数cld;置DF=0,地址增加again:movsb;传送一个字节dec cx;传送次数减1jnz again;判断传送次数cx是否为0;不为0,则到again位置执行指令;否则,结束,传送100个字节操作数的例子,例:字串传送,mov si,offset sourcemov di,offset destinationmov cx,50;cx传送次数cld;置DF=0,地址增加again:movsw;传送一个字dec cx;传送次数减1jnz again;判断传送次数cx是否为0;不为0,则到again位置执行指令;否则,结束,串读取LODS,LODSB;字节串读取:ALDS:SI;SISI1,LODSW;字串读取:AXDS:SI;SISI2,功能:将SI所指的源串中的一个字节(或字)存储单元中的数据取出来送入AL(或AX)中。即:字节操作:SIAL,字操作:SIAX。修改指针SI,使它指向串中的下一个元素。当DF=0时,SI增量。当DF=1时,SI减量。,串存储STOS,STOSB;字节串存储:ES:DIAL;DIDI1,STOSW;字串存储:ES:DIAX;DIDI2,功能:将AL或AX中的数据送入DI所指的目的串中的字节(或字)存储单元中。即:字节操作:ALDI,字操作:AXDI。修改指针DI,使之指向串中的下一个元素。当DF=0时,DI增量;当DF=1时,DI减量。,例:串存储,mov ax,0mov di,0mov cx,1000hcld;DF=0,地址增加again:stosw;传送一个字loop again;传送次数cx是否为0,stos指令应用:数据区初始化,结果是什么?,串比较CMPS,功能:将SI所指的源串中的一个字节(或字)存储单元中的数据与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存。即:(SI)(DI)。修改串指针,使之指向串中的下一个元素。当DF=0时,(SI)和(DI)增量。当DF=1时,(SI)和(DI)减量。,CMPSB;字节串比较:DS:SIES:DI;SISI1,DIDI1,CMPSW;字串比较:DS:SIES:DI;SISI2,DIDI2,特殊?,例:字符串比较,mov si,offset string1mov di,offset string2mov cx,countcldagain:cmpsb;比较两个字符jnz unmat;有不同字符,转移dec cxjnz again;进行下一个字符比较mov al,0;字符串相等,设置00hjmp output;转向outputunmat:mov al,0ffh;设置ffhoutput:mov result,al;输出结果标记,对string1和string2两个字符串进行比较,若串相同,在result单元中置0,否则置1,Loop again,串扫描SCAS,功能:AL(字节)或AX(字)中的内容与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,根据相减结果设置标志位,结果不保存。即:字节操作:(AL)(DI),字操作:(AX)(DI)。修改指针使之指向串中的下一个元素。当DF=0时,(DI)增量。当DF=1时,(DI)减量。,SCASB;字节串扫描:ALES:DI;DIDI1,SCASW;字串扫描:AXES:DI;DIDI2,例:查找字符串,利用scas指令可以进行搜索。把要搜索的关键字放在AL或AX中,用以搜索内存的某一数据块或字符串中,有无此关键字,若有,则把搜索次数记下来(若次数为0,表示无要搜索的关键字),并且记录下存放关键字的地址。程序一开始,当然要设置数据块的地址指针(scas指令要求设在DI中),要设立数据块的长度(要求设在CX中),把关键字送入AL或AX中。利用Z标志以判断是否搜索到,以便分别处理。,scas指令应用,例3:查找字符串,mov di,offset stringmov al,20h;空格的ASCII码值mov cx,countcldagain:scasb;搜索jz found;为0(ZF=1),发现空格dec cx;不是空格jnz again;搜索下一个字符.;不含空格,则继续执行found:.,重复前缀指令(rep),串操作指令执行一次,仅对数据串中的一个字节或字进行操作。但是在串操作指令前,都可以加一个重复前缀,实现串操作的重复执行。重复次数隐含在CX寄存器中重复前缀3条指令:REP、REPZ和REPNZ,REP重复前缀指令,REP前缀功能:当CX0时,重复执行后面的串指令。可以理解为每执行一次后面的串指令,CX减1,并回送CX,直到CX0,重复执行结束。例和例中,程序段的最后3条指令,可以分别替换为:REP MOVSB 和 REP STOSW,格式:REP串指令,说明:REP指令一般用在MOVS、STOS 指令前,重复串传送(例5),mov si,offset sourcemov di,offset destinationmov cx,100;cx传送次数cldrep movsb,again:movsb;传送一个字节dec cx;传送次数减1jnz again;判断传送次数cx是否为0;不为0(ZF=0),则转移again位置执行;否则,结束,重复串存储(例6),mov al,0mov di,0mov cx,8000hcldrep stosb,again:stosb;传送一个字dec cx;传送次数减1jnz again;判断传送次数cx是否为0,演示,REPZ重复前缀指令,REPZ/REPE前缀的功能:重复执行串指令的条件是:(CX0),且字符相等(ZF1)。可以理解为:每执行一次串指令,CX减1回送CX,并判断ZF是否为0,只要CX0或ZF0,重复执行结束,格式:REPZ串指令,说明:REPZ后面常跟CMPS串指令,用于字符串的比较。,REPNZ重复前缀指令,REPNZ/REPNE功能:重复执行后面串指令的条件是:(CX0)并且串不相等(ZF0)。可以理解为:每执行一次后面的串指令,CX减1,并判断ZF是否为1,只要CX0或ZF1,重复执行结束,格式:REPNZ串指令,说明:REPNZ后面常跟SCAS串指令,用于搜索一个字符。,例7:比较字符串(对例的改进),mov si,offset string1mov di,offset string2mov cx,countcldrepz cmpsb;重复比较两个字符jnz unmat;字符串不等,转移mov al,0;字符串相等,设置00hjmp output;转向outputunmat:mov al,0ffh;设置ffhoutput:mov result,al;输出结果标记,解释,重复比较的解释,指令repz cmpsb结束重复执行的情况 ZF0,即出现不相等的字符 CX0,即比较完所有字符:这种情况下,如果ZF0,说明最后一个字符不等;而ZF1表示所有字符比较后都相等,也就是两个字符串相同所以,重复比较结束后,jnz unmat指令的条件成立ZF0,字符串不相等,例8:查找字符串,mov di,offset stringmov al,20hmov cx,countcldrepnz scasb;搜索jz found;(ZF=1),发现空格.;不含空格,则继续执行found:.,Scasb指令的应用,使用重复前缀指令REP、REPZ、REPNZ前,需要初始化以下内容:源串地址指针SI目的串地址指针DI方向标志DF循环计数器CX,重复前缀指令小结,data segments1 db 100 dup(66h)s2 db 100 dup(00)data endscode segment assume cs:code,ds:data,es:datastart:mov ax,data mov ds,ax mov es,ax lea si,s1 lea di,s2,mov cx,100 cld rep movsb mov ah,4ch int 21hcode ends end start,例4.13字节数据串传送的例子。用带重复前缀的串操作指令实现,DATA SEGMENTblock dw count;block的元素个数 Dw 1234h,4321h,0abcdh,0b645h,8367h,3456h,6845h,0fffehcount=($-block)/2-1 buf1 dw 0;正数的个数 dw count dup(0);存放正数buf2 dw 0;负数的个数 dw count dup(0);存放负数DATA ENDS code segment assume cs:code,ds:data,es:datastart:mov ax,data mov ds,ax mov es,ax,例4.14 串指令LODS和STOS的应用例子。在block数据区有一组字数据,要求将正数和负数分开存放,并统计个数,lea si,block+2 lea di,buf1+2 lea bx,buf2+2 mov cx,block cldnext:lodsw test ax,8000h jnz fusu stosw inc buf1 jmp cont;*,fusu:xchg bx,di;*stosw xchg bx,di inc buf2 cont:loop next mov ah,4ch int 21hcode ends end start,思考:如果将test改为cmp,程序应做如何改动?,例8:查找字符串,例4.15 在字符串中查找空格的应用例子。若找到了,将0送入BX寄存器中;若未找到,将1送入BX寄存器中。(Scasb指令的应用),data segmentstring db how are you?count equ$-stringdata endscode segment assume cs:code,ds:data,es:datastart:mov ax,data mov ds,ax mov es,ax mov di,offset string,mov al,20hmov cx,countcldrepnz scasbjz foundmov bx,-1 jmp exitfound:mov bx,0exit:mov ah,4ch int 21hcode ends end start,例416:data segmentstr1 db 20,0,20 dup(?)str2 db 3,0,3 dup(?)data endscode segment assume cs:code,ds:data,es:datastart:mov ax,data mov ds,ax mov es,ax lea dx,str1 mov ah,0ah;mov ah,10 int 21h mov dl,0ah mov ah,2 int 21h,lea dx,str2 mov ah,0ah int 21h mov dl,0ah mov ah,2 int 21h mov cl,str1+1 xor ch,ch dec cx jz notexist mov al,str2+2 lea di,str1+2 cld,从键盘输入字符串str1与str2,其中str2长度小于str1,若str2是str1的子串,则输出“Y”,否则输出“N”,search:repne scasb jnz notexist mov dl,str2+3 cmp es:di,dl je exist jcxz notexist jmp searchnotexist:mov dl,n jmp dispexist:mov dl,ydisp:mov ah,2 int 21h,mov ah,4ch int 21hcode ends end start,思考,下面指令中,合理而有意义的指令是()。REP LODSB REP SCASB REP CMPSB REP MOVSB,(正向 DF0)串传送 MOVSB,串传送 MOVSW(反向 DF1),LODS(正向 DF0),STOS(反向 DF1),1,REP STOSB(正向 DF),设DF,REP MOVSB(正向 DF0),课间休息,