首页 理论教育 微型计算机原理-串处理指令及其分类

微型计算机原理-串处理指令及其分类

时间:2023-11-03 理论教育 版权反馈
【摘要】:串处理指令用来处理存放在存储器中的字节串或字串,包括传送、扫描、比较等。串处理指令主要分为三类:串处理指令、重复前缀以及方向标志设定指令。其中重复前缀是一种辅助指令,只能和串处理指令联合使用。

微型计算机原理-串处理指令及其分类

串处理指令用来处理存放在存储器中的字节串或字串,包括传送、扫描、比较等。串处理指令的处理方向由方向标志位DF决定,再加上重复前缀之后,串处理命令执行过程中可以自动将源串的指针SI和目的串的指针DI根据DF的指示进行自动增量(字节操作时+1,字操作时+2)或自动减量(字节操作时-1,字操作时-2)。

串处理指令主要分为三类:串处理指令、重复前缀以及方向标志设定指令。其中重复前缀是一种辅助指令,只能和串处理指令联合使用。方向标志设定指令同时也是一种处理器控制指令。

1.方向标志设定指令

方向标志设置指令用于设置8086微处理器的DF标志位,包括CLD和STD两条指令。

●CLD

格式:CLD

执行的操作:将DF清0,在执行串处理指令时可使地址自动增量。

●STD

格式:STD

执行的操作:将DF置1,在执行串处理指令时可使地址自动减量。

为了处理连续存储单元中的字符串或数串,地址指针需要连续增量或减量,指针的增量或减量决定了串的处理方向。当DF=0时,源串指针SI和目的串指针DI自动增量。当DF=1时,源串指针SI和目的串指针DI自动减量。地址指针在增量或减量时的幅度是1还是2则取决于串操作数是字节还是字,如果串操作数是字节,则增减量的幅度是1,如果串操作数是字,则增减量的幅度是2。

2.串处理指令与重复前缀

串处理指令主要包括串传送、存串、取串、串比较、串扫描五种,每种串处理指令又包括字节处理指令和字处理指令两条,这样我们就有了十条串处理命令。

●MOVSB

字节串传送指令,执行如下操作:

1)((ES:DI))←((DS:SI)),传送一个字节;

2)(SI)←(SI)±1,(DI)←(DI)±1,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

●MOVSW

字串传送指令,执行如下操作:

1)((ES:DI))←((DS:SI)),传送一个字(2字节);

2)(SI)←(SI)±2,(DI)←(DI)±2,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

MOVSB和MOVSW指令又可以统称为MOVS指令,它们不影响条件码。

MOVS指令可以把由(SI)指向的数据段中的一个字(或字节)传送到由(DI)指向的附加段中的一个字(或字节)中去,同时根据方向标志及数据格式(字或字节)对SI和DI进行修改(±1或±2)。

●重复前缀REP

MOVS指令只能完成一个字节或一个字的传送,但这是远远不够的,我们经常需要的是完成一个字串或字节串的传送,这就意味着必须重复MOVS指令的动作。在8086微处理器的指令系统中,一个特别的指令前缀REP就可以配合MOVS指令做到这一点。REP指令的格式:

REP <串操作指令(MOVS、STOS)>

REP指令执行的操作:

1)如(CX)=0则退出REP,否则往下执行;

2)(CX)←(CX)-1;

3)执行其后的串指令;

4)重复(1)~(3)。

当MOVS指令与前缀REP联用时,就可以将数据段中的整串数据传送到附加段中。这里源串在数据段中,并允许使用段跨越前缀来修改,而目的串必须在附加段中。在MOVS指令与前缀REP联用时还必须先把数据串的长度送到CX寄存器中,以便控制指令结束。因此在执行该指令前,应该先做好以下准备。

1)把存放于数据段中的源串首地址(如反向传送则应是末地址)放入SI寄存器中;

2)把将要存放数据串的附加段中的目的串首地址(或反向传送时的末地址)放入DI寄存器中;

3)把数据串长度放入CX寄存器;

4)建立方向标志。

在完成这些准备工作后就可使用串指令REP MOVSB或REP MOVSW实现传送了。需要注意的是,CX中存放的数据串长度是传送数据的次数而不是数据的字节数。当传送字节串时,传送次数等于传送的字节数,而传送字串时,传送次数是传送的字节数的一半。

例:

在数据段中有一个字符串,其长度为17,要求把它们传送到附加段中的一个缓冲区中。编制程序如下所示。其中MESS1为源串,存放在数据段中从符号地址MESS1开始的存储区内,每个字符占有一个字节。MESS2为目的串,存放在附加段中从符号地址MESS2开始的17个字节的存储区内。

这段程序首先将DS和ES赋值为DATA段和EXTRA段的段首地址,随后用两条LEA命令为SI和DI两个寄存器赋值,分别使DS:SI和ES:DI指向MESS1和MESS2,接下来的一条MOV指令将CX设为17,即字符串的长度,一条CLD指令将DF标志位清零,指定字符串传送的增量方向为地址自动增量,最后用一条REP MOVSB指令将数据段中从MESS1开始的17个字符传送到附加段中从MESS2开始的17个字节存储空间中。

●STOSB

字节串存储指令,执行如下操作:

1)((ES:DI))←(AL),将AL中的内容存储到ES:DI指向的字节中;

2)(DI)←(DI)±1,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

●STOSW

字节串存储指令,执行如下操作:

1)((ES:DI))←(AX),将AX中的内容存储到ES:DI指向的字中;

2)(DI)←(DI)±2,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

STOSB和STOSW指令又可以统称为STOS指令,它们不影响条件码。

重复前缀REP不仅可以用于MOVS命令来实现串的传送,还可以用于STOS命令来实现字节串或字串的初始化。首先将ES:DI设为要初始化的字节串或字串的首地址并把DF清零(或把ES:DI设为要初始化的字节串或字串的尾地址并把DF置1),然后把CX设为要初始化的字节串或字串的长度,AL或AX设为字节串或字串要初始化的值,最后一条REPSTOSB或REP STOSW就可以完成字节串或字串的初始化工作了。

例:

下面这段程序实现将从MESS地址开始的15个字初始化为0A0AH的工作。

●LODSB

字节串读取指令,执行如下操作:(www.xing528.com)

1)(AL)←((DS:SI)),将ES:DI指向的字节中的内容读取到AL中;

2)(SI)←(SI)±1,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

●LODSW

字节串读取指令,执行如下操作:

1)(AX)←((DS:SI)),将ES:DI指向的字中的内容读取到AX中;

2)(SI)←(SI)±2,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

和STOSB/STOSW串存储指令相对应,8086微处理器也支持LODSB/LODSW串读取指令,这两条指令负责将源串指针(DS:SI)指向的存储器中的内容读取到AL或AX中,并将源串指针指向下一个要处理的字节或字。和STOSB/STOSW不同的是,这两条指令通常单独使用而不与REP重复前缀配合使用。

LODSB和LODSW指令又可以统称为LODS指令,它们不影响条件码。

除了用于串传送的MOVS、STOS和LODS指令以外,8086微处理器还提供了两条用来实现串比较的指令,它们是CMPS和SCAS,分别用于比较两个串和在串中扫描特定字节或字。

●CMPSB

字节串比较指令,执行如下操作:

1)((DS:SI))-((ES:DI)),比较DS:SI和ES:DI存储器单元中的字节,比较的方法和CMP指令相同,用比较的结果设置条件码;

2)(SI)←(SI)±1,(DI)←(DI)±1,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

●CMPSW

字串比较指令,执行如下操作:

1)((DS:SI))-((ES:DI)),比较DS:SI和ES:DI存储器单元中的字,比较的方法和CMP指令相同,用比较的结果设置条件码;

2)(SI)←(SI)±2,(DI)←(DI)±2,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

CMPSB和CMPSW指令又可以统称为CMPS指令,它们用于对两个字节串或字串中的一个字节或字进行相减比较,不保存相减的结果但用比较结果设置标志位,标志位的设定方式和CMP指令相同。

CMPS指令一般不和REP指令前缀配合使用,和CMPS指令配合使用的是另外两个指令前缀:REPE/REPZ和REPNE/REPNZ。

●REPE/REPZ指令前缀

格式:REPE(或REPZ)<串操作指令(CMPS或SCAS)>

REPE/REPZ指令执行的操作:

1)如(CX)=0或ZF=0当某次比较的结果两个操作数不等时退出,否则往下执行;

2)(CX)←(CX)-1;

3)执行其后的串指令;

4)重复(1)~(3)。

实际上REPE和REPZ是完全相同的,它们的机器码是一样的,只是汇编助记符不同而已。与REP相比,除满足(CX)=0的条件可结束操作外,REPE/REPZ前缀还增加了ZF=0的条件。也就是说,只要两数相等就可继续比较,如果遇到两数不相等时可提前结束操作。

●REPNE/REPNZ指令前缀

格式:REPNE(或REPNZ)<串操作指令(CMPS或SCAS)>

REPNE/REPNZ指令执行的操作:

1)如(CX)=0或ZF=1当某次比较的结果两个操作数相等时退出,否则往下执行;

2)(CX)←(CX)-1;

3)执行其后的串指令;

4)重复(1)~(3)。

和REPE/REPZ指令前缀一样,实际上REPNE和REPNZ是完全相同的,它们的机器码是一样的,只是汇编助记符不同而已。与REP相比,除满足(CX)=0的条件可结束操作外,REPNE/REPNZ前缀还增加了ZF=1的条件。也就是说,只要两数不等就可继续比较,如果遇到两数相等时可提前结束操作。

和REP指令前缀相比,REPE/REPZ和REPNE/REPNZ指令前缀在重复次数限制的基础之上又增加了重复条件限制,这就使REPE/REPZ和REPNE/REPNZ指令前缀更加适合于和CMPS或SCAS这样的影响标志位的串操作指令相配合使用。

例:

我们可以用下面这样一段代码来比较两个字节串是否相同,并找出不同的第一个字节。

在这段代码中,开始的几个MOV指令用来设置DS和ES段寄存器,然后用两条LEA指令初始化SI和DI寄存器,MOV CX,17指令用来将CX设为字节串的长度(17个字节),CLD指令清除DF标志位,将串操作的方向设为从低地址到高地址。随后,一条REPE CMPSB指令负责实现字节串的比较,该指令从字节串的开头向结尾方向一一比较两个字节串的每个字节,直到17个字节都比较完或比较的结果设置ZF为0(即两个字节串对应字节不相同)为止。随后的JCXZ指令则根据CX是否为0判定两个字节串是否相同,如果相同,则转移到EQU:标号处继续执行。如果不相同,NOTEQU:标号后面的两条DEC指令将SI和DI分别减1,以使SI和DI分别指向源串和目标串中第一个不同的两个字节。(思考题:为什么要减1?)

除了CMPS之外,SCAS指令也是经常和REPE/REPZ和REPNE/REPNZ指令前缀配合使用的指令。

●SCASB

字节串扫描指令,执行如下操作:

1)(AL)–((ES:DI)),比较AL寄存器和ES:DI存储器单元中的字节,比较的方法和CMP指令相同,用比较的结果设置条件码;

2)(DI)←(DI)±1,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

●SCASW

字串扫描指令,执行如下操作:

1)(AX)–((ES:DI)),比较AX寄存器和ES:DI存储器单元中的字,比较的方法和CMP指令相同,用比较的结果设置条件码;

2)(DI)←(DI)±2,当方向标志DF=0时用加法,当方向标志DF=1时用减法。

SCASB和SCASW指令又可以统称为SCAS指令,和CMPS指令一样,它们也执行和CMP指令相同的比较并设置标志位的动作,只是参加比较的双方变成了AL/AX寄存器和ES:DI指向的存储器单元中的内容。一种SCAS指令经常被用来实现的功能是在一个字节串或字串中寻找某特定字节或字,这也是SCAS指令中“扫描”(SCAN)一词的来源。

例:

在一个字符串中“扫描”一个指定字符的功能可以用下面这段程序来完成。

总的来讲,这段代码和前面CMPS指令示例的那段代码很相近。代码中,LEA指令初始化DI寄存器,MOV AL,‘O’指令设定要扫描的目标字符为大写字母O,MOV CX,17指令用来将CX设为字节串的长度(17个字节),CLD指令清除DF标志位,将串操作的方向设为从低地址到高地址。随后,一条REPNE SCASB指令负责实现字节串的扫描,该指令从字节串的开头向结尾方向一一扫描字节串的每个字节,直到17个字节都扫描完或对应字节和AL比较的结果设置ZF为1(即该字节与AL中的内容相同)为止。随后的JCXZ指令则根据CX是否为0判定是否找到了与AL中内容相同的字节,如果未找到(即CX=0),则转移到NOTF:标号处继续执行。如果CX不为0,则意味着找到了与AL中内容相同的字节,则FOUND:标号后面的DEC指令将DI减1,以使DI分别指向目标串中第一个与AL中内容相同的字节(即第一个大写字母‘O’)。(请思考:为什么要减1?)

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈