第08章-循环程序设计_第1页
第08章-循环程序设计_第2页
第08章-循环程序设计_第3页
第08章-循环程序设计_第4页
第08章-循环程序设计_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章循环程序设计8.1循环程序结构(1)置循环初值部分(这一部分仅执行一次)有两方面的作用:为循环工作部分置初值,包括对工作部分所涉及的某些寄存器或存储单元置零或置其他初始值,使地址指针指向一个数据区的起始位置等;为循环控制部分置初值,包括置循环次数或置循环结束条件等。8.1循环程序结构(2)循环工作部分(需要重复执行的程序段,是循环程序要完成的具体操作)(3)循环控制部分(随循环工作部分一道重复执行)作用是修改用于循环计数的寄存器的值,以及对循环结束条件是否成立作出判断。【例8.1】将BLKS为首址的连续N个字节数传送至BLKD为首址的存储区,且假设这两个存储区不重叠,则程序流程图如右图所示。8.2循环指令8.2.1重复控制指令一般格式:

XXXX短标号功能:将寄存器CX默认为重复控制计数器,根据(CX)是否为0等情况来控制是转向短标号处,还是顺序执行其后的指令(指令指定的短标号位置一般在该重复控制指令之上,转向短标号处就实现了对上面程序段的重复执行)。8.2.1重复控制指令1.LOOP指令

该指令首先使寄存器CX中的计数值减1,然后判断(CX)是否为零。若(CX)≠0则转至该指令指定的短标号处,即重复执行短标号开始的程序段;否则顺序执行该LOOP指令后的指令,即不再重复执行短标号开始的程序段。1.LOOP指令【例8.2】以下程序段的功能是,求BUFF数据区中各字节之和,并送SUM变量。

BUFFDB40H,82H,0F2H,05H,0,10H,0,18HSUMDW?

XORAX,AX

MOVSI,OFFSETBUFF

MOVCX,8

;置循环次数8AGAIN:ADDAL,[SI]ADCAH,0INCSI

;循环工作部分;LOOPAGAIN;循环控制。

MOVSUM,AX8.2.1重复控制指令2.LOOPZ指令

该指令与LOOP指令的区别仅在于,在判断(CX)是否为零的同时还要判断ZF标志。若(CX)≠0且ZF=1则转至该指令指定的短标号处;否则顺序执行LOOPZ指令后的指令。8.2.1重复控制指令3.LOOPNZ指令该指令与LOOP指令的区别仅在于,若(CX)≠0且ZF=0则转至该指令指定的短标号处;否则顺序执行LOOPNZ指令后的指令。【例】以下程序的功能是什么?

……BUFFDB40H,82H,0F2H,05H,0,10H,0,18HSUMDW?

.

……

XORAX,AXMOVSI,OFFSETBUFFMOVCX,8AGAIN:ADDAL,[SI]ADCAH,0INCSI

CMPBYTEPTR[SI],0LOOPNZAGAIN

MOVSUM,AX程序功能:求BUFF数据区中第一个零元素之前的各字节数之和,并送SUM变量。

……BUFFDB40H,82H,0F2H,05H,0,10H,0,18HSUMDW?.

……

XORAX,AXMOVSI,OFFSETBUFFMOVCX,8AGAIN:ADDAL,[SI]ADCAH,0INCSI

CMPBYTEPTR[SI],0LOOPNZAGAIN

MOVSUM,AX8.2.2串操作指令及重复前缀1.MOVSB、MOVSW指令(串传送指令)将DS:SI所指的源操作数传送到ES:DI所指的目的位置(指令MOVSB实现字节传送,MOVSW实现字传送);然后修改SI、DI的内容使之指向下一元素位置。对SI、DI的修改取决于两个因素:其一是操作数的属性;其二是方向标志DF的状态。具体修改方法:

MOVSB指令:若DF=0则SI、DI加1;否则SI、DI减1。

MOVSW指令:若DF=0则SI、DI加2;否则SI、DI减2。1.MOVSB、MOVSW指令(串传送指令)该指令不影响状态标志。在其前加上重复前缀REP可实现串从一个存储区到另一个存储区的传送。在使用重复前缀的情况下,应预先将重复次数送寄存器CX,并根据需要使用指令CLD使DF置“0”,或使用指令STD使DF置“1”。【例8.4】

以下程序的功能等同于【例8.1】中的程序功能。

DSEGSEGMENTBLKSDB(N个字节数)NEQU$-BLKS……BLKDDBNDUP(?)DSEGENDSCODESEGMENTASSUMEDS:DSEG,ES:DSEG,

CS:CSEGST:MOVAX,DSEGMOVDS,AX;置源串段地址

MOVES,AX;置目的串段地址MOVCX,N;置串操作重复次数MOVSI,OFFSETBLKS;置源串偏移地址;MOVDI,OFFSETBLKD;置目串偏移地址;CLD;DF←0;设置“+”修改;REPMOVSB;重复N次字节传送操作;MOVAH,4CHINT21H;返回DOSCSEGENDSENDST8.2.2串操作指令及重复前缀2.LODSB、LODSW指令(串装入指令)与MOVSB、MOVSW指令的区别仅在于,这两条指令所作数据传送的目的位置分别为AL、AX,不涉及寄存器DI。8.2.2串操作指令及重复前缀3.STOSB、STOSW指令(串存储指令)与MOVSB、MOVSW指令的区别仅在于,这两条指令源操作数分别为(AL)、(AX),不涉及寄存器SI。在其前加上重复前缀REP可以使一个存储区各单元置同一数据。【例】

以下程序的功能是什么?

DSEGSEGMENTBUFFDB100DUP(?)DSEGENDS;CSEGSEGMENTASSUMEES:DSEG,

CS:CSEGST:MOVAX,DSEGMOVES,AXMOVAH,01HINT21HMOVDI,OFFSETBUFFMOVCX,100CLDREPSTOSBMOVAH,4CHINT21HCSEG ENDS ENDSST功能:使BUFF数据区各单元存放用户输入的同一个字符。

DSEGSEGMENTBUFFDB100DUP(?)DSEGENDS;CSEGSEGMENTASSUMEES:DSEG,

CS:CSEGST:MOVAX,DSEGMOVES,AXMOVAH,01HINT21HMOVDI,OFFSETBUFFMOVCX,100CLDREPSTOSBMOVAH,4CHINT21HCSEG ENDS ENDSST8.2.2串操作指令及重复前缀4.CMPSB、CMPSW指令(串比较指令)将DS:SI所指的源操作数减去ES:DI所指的目的操作数,即DS:[SI]-ES:[DI](注意:不是ES:[DI]-DS:[SI]),但不回送差值,只是根据减法运算产生状态标志。这两条指令对SI、DI的修改分别与MOVSB、MOVSW相同。8.2.2串操作指令及重复前缀5.SCASB、SCASW指令(串搜索指令)与CMPSB、CMPSW指令的区别仅在于,这两条指令所规定的被减数分别为(AL)、(AX),不涉及寄存器SI。在其前加上重复前缀REPZ或REPNZ,可以在ES:DI所指的一个存储区中寻找与(AL)、(AX)不等或相等的元素。8.2.2串操作指令及重复前缀6.REP前缀使所缀的串操作指令重复CX初值所指定的次数。在使用该前缀及其串操作指令前,应根据需要对CX设置初值。REP前缀常配合MOVSB/MOVSW,STOSB/STOSW指令使用。

8.2.2串操作指令及重复前缀7.REPZ前缀当所缀的串操作指令尚未执行CX初值所指定的次数,且所缀串操作指令的执行使得ZF=1,则重复执行所缀的串操作指令;否则顺序执行串操作指令的下一指令。REPZ前缀常配合CMPSB/CMPSW、SCASB/SCASW指令使用。8.2.2串操作指令及重复前缀8.REPNZ前缀与REPZ前缀的区别仅在于,使所缀的串操作指令重复执行的条件不同。当所缀的串操作指令尚未执行CX初值所指定的次数,且所缀串操作指令的执行使得ZF=0,则重复执行所缀的串操作指令;否则顺序执行串操作指令的下一指令。【例】

以下程序的功能是什么?

DSEGSEGMENTBUFFDB40H,82H,0F2H,05H,0,10H,0,18HANSDB?DSEGENDS;CSEG SEGMENTASSUMEES:DSEG,CS:CSEGST:MOVAX,DSEGMOVES,AXXORAL,ALMOVDI,OFFSETBUFFMOVCX,8

CLD

REPNZSCASB MOVAL,ES:[DI] MOVANS,AL

MOVAH,4CH INT21HCSEGENDS ENDSSTART功能:将BUFF数据区中紧接第一个零元素后的字节数送ANS单元(设在末元素前存在零元素)。

DSEGSEGMENTBUFFDB40H,82H,0F2H,05H,0,10H,0,18HANSDB?DSEGENDS;CSEG SEGMENTASSUMEES:DSEG,CS:CSEGST:MOVAX,DSEGMOVES,AXXORAL,ALMOVDI,OFFSETBUFFMOVCX,8

CLD

REPNZSCASB MOVAL,ES:[DI] MOVANS,AL

MOVAH,4CH INT21HCSEGENDS ENDSSTART8.3循环程序设计

8.3.1计数控制的循环程序设计在循环程序设计中,用计数的方法实现循环控制是一种基本且常用的方法。这种方法适用于已知循环次数的场合。按题意确定需要重复进行的操作,将其作为循环工作部分对循环工作部分所涉及的某些寄存器、存储单元置初始值,对计数寄存器CX置循环次数;根据计数情况控制循环,通常使用LOOP指令实现(在循环部分只是一条串操作指令时,则可通过在该串操作指令前加上REP前缀来实现)。【例8.7】

编写计算N!的程序。

编程思路:(1)循环工作部分包括乘法运算。考虑到对于一个不大的N

值,N!的数值也会很大,为提高程序的适应性,故使用16位寄存器,宜使用AX作为累乘器。在使用乘法指令时,AX既提供被乘数,又存放乘积。使用另一个16位寄存器提供乘数i(i=1,2,……N),考虑到LOOP指令的功能,故宜使用CX提供乘数。【例8.7】

编写计算N!的程序。

(2)置循环初值部分包括:累乘器的AX应置初值1。为CX置什么初值?若置初值1,则在循环工作部分应使其增1,且在循环控制部分要判断(CX)是否等于N值。考虑到LOOP指令本身具有使CX减1,且根据(CX)是否为0来确定是否重复执行循环工作部分的功能,故宜对CX置初值N。(3)循环控制只要使用LOOP指令即可。

计算N!的程序。

(2)置循环初值部分包括:累乘器的AX应置初值1。为CX置什么初值?若置初值1,则在循环工作部分应使其增1,且在循环控制部分要判断(CX)是否等于N值。考虑到LOOP指令本身具有使CX减1,且根据(CX)是否为0来确定是否重复执行循环工作部分的功能,故宜对CX置初值N。(3)循环控制只要使用LOOP指令即可。

计算N!的程序。DSEGSEGMENTNEQU(一个自然数)ANSDW?DSEGENDS;CSEG SEGMENTASSUMEDS:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AX

MOVCX,NMOVAX,1;置循环初值;NT:MULCX;循环工作;LOOPNT;循环控制;MOVANS,AX;MOVAH,4CHINT21H;返回DOS。CSEGENDSENDSTART

8.3.2条件控制的循环程序设计

1.已知最大循环次数的条件控制循环程序设计(1)使用计数控制的循环程序设计方法,并在循环工作部分根据执行情况判断是否中途跳出循环。(2)使用LOOPZ、LOOPNZ指令实现循环的条件控制。

(3)使用带有REPZ、REPNZ前缀的串比较、串搜索指令实现循环的条件控制。【例8.9】

编写一程序,用以判断BUF1和BUF2两个等长度的数据区中数据是否相同。相同则使FLAG单元置0,否则置-1。方法一:DSEG

SEGMENTBUF1

DB(N个字节数)BUF2

DB(N个字节数)COUNT

EQU

$-BUF2FLAG

DB

0DSEG

ENDS

……MOV

SI,OFFSET

BUF1-1MOV

DI,OFFSET

BUF2-1MOVCX,COUNTNT:INC

SIINC

DIMOV

AL,[SI]

CMP

AL,[DI]

JZ

L1MOV

FLAG,-1JMP

OKL1:LOOP

NTOK:MOV

AH,4CHINT

21H……方法二DSEG

SEGMENTBUF1

DB(N个字节数)BUF2

DB(N个字节数)COUNT

EQU

$-BUF2FLAG

DB

0DSEG

ENDS……MOV

SI,OFFSETBUF1-1MOV

DI,OFFSETBUF2-1MOVCX,COUNTNT:INCSIINCDIMOVAL,[SI]CMPAL,[DI]

LOOPZNTJZOKMOVFLAG,-1OK:MOVAH,4CHINT21H;返回DOS……方法三ASSUMEDS:DSEG,ES:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AX

MOVES,AX

MOVSI,OFFSETBUF1MOVDI,OFFSETBUF2MOVCX,COUNTCLD

REPZCMPSBJZOKMOVFLAG,-1OK:8.3.2条件控制的循环程序设计2.循环次数未知的条件控制循环程序设计【例8.12】

编写一程序,求满足<8000的最大的X值。DSEGSEGMENTCONSEQU8000X DW?DSEGENDSCSEGSEGMENTASSUMEDS:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AXXORAX,AXXORBX,BX;置循环初值NEXT: INCBXADDAX,BX;循环工作;

CMPAX,CONSJBNEXT;循环控制;

DECBXMOVX,BX

MOVAH,4CHINT21H;返回DOSCSEG ENDSENDST8.3.3多重循环程序设计【例8.13】编写一程序,用以统计BUF数据区的64个字节中,“0”二进制位的数目。分析:(1)一个字节中“0”二进制位数目的统计可以用重复次数为8的循环结构解决;对64个字节的处理可以用重复次数为64的循环结构解决;前一循环结构作为本循环结构的循环工作部分,即使用二重循环就可以完成题目给定的功能。【例8.13】编写一程序,用以统计BUF数据区的64个字节中,“0”二进制位的数目。(2)内层循环的构成。a.循环工作部分:判断一个字节(如SI所指字节)的某一位是否为“0”,为“0”则使计“0”寄存器(如BX)增1;否则跳过增1操作。b.置循环初值部分:计“0”寄存器置初值0,循环计数寄存器(如DH)置初值8。c.循环控制部分:对循环计数寄存器作减1计数,若减1后不为0,则重复执行循环工作部分,否则结束循环。【例8.13】编写一程序,用以统计BUF数据区的64个字节中,“0”二进制位的数目。(3)外层循环的构成a.循环工作部分:内层循环,修改地址指针SI,并将内层循环产生的(BX),即一个字节中“0”二进制位的数目累加到某个内存单元(如COUNT单元)。b.置循环初值部分:作为存放所有字节中“0”二进制位数目的内存单元置初值0(这一工作可通过伪指令实现);地址指针SI指向BUF数据区起始位置;外循环计数器CX置初值64。c.循环控制使用LOOP指令即可。DSEGSEGMENTBUF DB(64个字节数)COUNTDW0DSEGENDSCSEGSEGMENTASSUMEDS:DSEG,CS:CSEGST:MOVAX,DSEGMOVDS,AXMOVSI,OFFSETBUFMOVCX,64;置外循环初值EXL:XORBX,BXMOVDH,8MOVAL,[SI];置内循环初值

INL:RORAL,1JCNEXTINCBX;内层循环工作

NEXT:DECDHJNZINL;内循环控制

INCSIADDCOUNT,BX;外循环工作

LOOPEXL;外循环控制对该程序思考两个问题:1)内层循环为何不使用LOOP指令作循环控制?2)在该程序中BX用做一个字节的计“0”寄存器,每当一个字节中“0”二进制位的个数统计完毕,则将(BX)加到COUNT单元中,这一相加工作要进行64次。如果将BX改作所有字节的计“0”寄存器,最后一次性将(BX)送COUNT单元,则程序将更为简洁,而且程序执行将更快。为此程序应如何修改?【例8.14】编写一程序,以实现N个无序的有符号字节数组由大到小的排序

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论