您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 咨询培训 > 4-4循环程序设计.
章汇编语言程序设计•循环程序有两种结构:“先执行,后判断”和“先判断,后执行。4.4.4循环结构程序初始化循环体参数修改循环控制?YN程序当中有一部分指令,需要反复的执行,需要编写循环结构程序。初始化循环体修改参数循环控制?YN先执行,再判断条件。先判断条件,再执行•无论哪种结构,循环程序都可由如下四部分组成:(1)循环初始化部分循环之前的一些准备工作。比如数据处理一般要设置地址指针、循环次数及某标志的设置,相关寄存器的清零等操作。只有正确地进行了初始化设置,循环程序才能正确运行,及时停止。(2)循环体:是要重复执行的那部分指令或程序段。(3)修改参数:为下一次循环做些准备。比如说地址指针的修改,循环次数的检验(4)循环控制:就是循环的判别,我这次循环是否该结束了循环结束的控制:用计数器控制循环结束。(见实例)用特征码控制循环结束。(见实例)循环程序结构•【例1】※设内存BUFF开始的单元中依次存放着30个8位无符号数,求它们的和并放在SUM单元中,试编写程序MOVSI,BUFF;设地址指针MOVCX,30;设计数初值XORAX,AX;设累加器初值(标志位清零AGAIN:ADDAL,[SI]ADCAH,0;INCSILOOPAGAIN;循环累加MOVSUM,AX循环程序结构解决ADDAL,[SI]的进位问题AH=AH+0+CF数据段怎么处理?•[例2]统计以BUFFER为起始地址的100个单元中负数的个数,并将统计出来的负数个数送NUM单元。(P145)XORBL,BL;存放负数的个数MOVCX,100;统计次数LEASI,BUFFERCLDNEXT:LODSB;取一个数TESTAL,80HJZGOONINCBLGOON:LOOPNEXT;是负数,计数器加1MOVNUM,BL••例3将BX中的16进制数转换为ASCII码,存放到BUF开始的内存单元中,并在屏幕上显示出数值。•数字0—9对应的ASCII码为30H---39H(加30H)•数字A—F对应的ASCII码为41H---46H(加37H)循环程序结构•MOVSI,OFFSETBUFMOVCH,4;四个16进制数需要处理NEXT:MOVCL,4;左移4位ROLBX,CLMOVAL,BLANDAL,0FHCMPAL,0AHJCSTOREADDAL,7HSTORE:ADDAL,30HMOV[SI],ALMOVAH,2MOVDL,ALINT21HINCSIDECCHJNZNEXTHLT循环程序结构•循环程序结构•例[4]※统计AX寄存器中1的个数,结果放到CL寄存器中。•MOVCL,0;将来放1的个数•L1:ANDAX,AX;AX不变,但影响ZF标志位•JZSTOP;如果AX=0那么下面的程序就不必要了•SALAX,1;算术左移,将最低位送入CF•JNCL2;检验CF的值是1还是0?•INCCL•L2:JMPL1•STOP:MOVAH,4CH•INT21H该程序没有设置循环次数,看AX是不是0决定是否循环•循环程序结构•参考程序(2)•MOVCH,16•MOVCL,0•L1:SALAX,1•JNCL2•INCCL•L2:DECCH•JNZL1•STOP:MOVAH,4CH•INT21H•先判断,后执行该程序有设置循环次数,看CH是不是0决定是否循环8.5子程序设计1.子程序的定义程序设计中,把多次重复出现、具有通用性、能够完成特定处理任务的程序段编写成独立的程序模块。特性:(1)重复性;(2)通用性;(3)浮动性;(4)模块化;8.5.1子程序概念主程序与子程序调用关系主程序K:调用子程序ADK:……J:调用子程序ADJ:…………子程序A……返回主程序8.5.1子程序概念MAINPROCFAR;主程序……CALLSUBR1……RETMAINENDPSUBR1PROCNEAR;子程序(NEAR可省略)……RETSUBR1ENDPMAIN及其子程序SUBR1在同一代码段中,SUBR1定义为NEAR属性。如果调用程序和子程序不在同一个代码段中,则使用FAR属性程序的主程序看作DOS调用的一个子程序,因而DOS对MAIN的调用以及MAIN中的RET就是FAR属性。8.5.1子程序概念CALL和NEAR为调用指令基本功能:将子程序的返回地址(即CALL指令的下一条指令的地址,简称断点地址,包括段地址和偏移地址)压入堆栈,以便执行完子程序后能返回主程序,并从断点处继续往下执行,然后按照某种寻址方式转向子程序的入口地址去执行子程序。子程序定义的语法格式:子程序名PROCAttribute…….RET子程序名ENDP子程序定义的语法格式SUBTPROCPUSHAX;现场保护PUSHBXPUSHCXPUSHDX……;子程序体POPDX;现场恢复POPCXPOPBXPOPAXRETSUBTENDP例5-13PUSH指令把子程序所需要使用的寄存器内容保存在堆栈中POP指令把寄存器内容恢复原状子程序结构形式—保护现场与恢复现场注意:子程序中用到的寄存器是应该保护的。如果使用寄存器在主程序和子程序之间传送参数,这种寄存器就不一定需要保护,特别是向主程序回送结果的寄存器,更不应该因保存和恢复寄存器而破坏了应该向主程序传送的信息。先入后出的原则掌握以下几点:调用子程序用CALL指令,返回调用程序用RET指令。子程序允许嵌套调用。进入子程序后首先要保护主程序的运行状态(标志位)和使用的寄存器内容(称为保护现场),退出子程序前要恢复现场。调用前要预先确定子程序中要使用哪些寄存器,并定义入口参数和出口参数。参数传递可利用寄存器、存储单元或堆栈(要用BP寻址)。子程序设计举例子程序设计——参数传递方法1.利用寄存器:主程序把给子程序的参数直接放在的约定的寄存器,子程序从中取参数;子程序处理结果也放在约定寄存器中。2.利用存储单元:这种参数传递方法,把所需传递的参数直接放在子程序调用指令代码之后。3.利用堆栈:这种方法将参数压入堆栈,在子程序运行时从堆栈中取参数。返回主程序后主程序从堆栈中取结果。入口参数:主程序送给子程序处理的信息出口参数:子程序送给主程序的处理结果【例1】两个6字节数相加。分析:将一个字节相加的程序段设计为子程序。主程序分3次调用该子程序,但每次调用的参数不同。DATASEGMENTADD1DBFEH,86H,7CH,35H,68H,77HADD2DB45H,BCH,7DH,6AH,87H,90HSUMDB6DUP(0)COUNTDB6DATAENDSSTACKSEGMENTDB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACKMADD:MOVAX,DATAMOVDS,AXMOVAX,STACKMOVSS,AXMOVSI,OFFSETADD1MOVDI,OFFSETADD2MOVBX,OFFSETSUMMOVCX,COUNT;循环初值为6CLCAGAIN:CALLSUBADD;调用子程序LOOPAGAIN;循环调用6次MOVAX,4C00HINT21H子程序入口参数:SI,DI,BX出口参数:SI,DI,BXSUBADDPROC;完成一个字节相加PUSHAX;保护AX的值MOVAL,[SI];SI是一个源操作数指针ADCAL,[DI];DI是另一个源操作数指针MOV[BX],AL;BX是结果操作数指针INCSIINCDIINCBXPOPAX;恢复AX的值RETSUBADDENDPCODEENDSENDMADD•子程序设计[例4-16]从一个字符串删去一个字符。DATASEGMENTSTRINGDB‘Exxperince’LENGTHDW$_STRINGKEYDB‘X’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARSTART:MOVAX,DATAMOVDS,AXLEABX,STRING多余的字符•,LENGTHPUSHBXPUSHCXMOVAL,KEYCALLDELCHARMOVAH,4CHINT21HMAINENDPDELCHARPROCPUSHBPMOVBP,SPPUSHSIPUSHDIPUSHCX(BX)(CX)(IP)原(BP)(SI)(DI)(CX)(SP)(BP)返回地址程序执行时堆栈最满时的状态•,[BP+4]MOVCX,[SI]MOVDI,[BP+6]REPNESCASBJNEDONEMOVSI,[BP+4]DECWORDPTR[SI]MOVSI,DIDECDIREPMOVSBDONE:POPCXPOPDIPOPSIPOPBPRET4DELCHARENDPCODEENDSENDSTART•[例4-18]当I/O状态端口0378H的Bit1为0时,表示外设忙;为1则表示外设可以接收数据。现将当前数据段中从BUFFER开始的连续100个字节的内容从I/O数据端口03F8H输出到外设。SENDATAPROCFARPUSHAXPUSHDXPUSHSIPUSHCXLEASI,BUFFERMOVCL,100AGAIN:MOVDX,0378HWAIT:INAL,DXTESTAL,02HJZWAIT•,[SI]MOVDX,3F8HOUTDX,ALINCSIDECCLJNZAGAINPOPCXPOPSIPOPDXPOPAXRETSENDATAENDP•‘2’,‘6’,‘A’,‘1’MBINDB2DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATABEGIN:MOVAX,DATAMOVDS,AXMOVCL,4MOVCH,CLLEASI,MASCCLD[例4-19]把ASCII码形式表示的数转换为二进制码。ASCII码存放在以MASC为首地址的内存单元中,转换结果放MBIN。•,AXXORDX,DXNEXT1:LODSMASCANDAL,7FHCMPAL,‘0’JLERRORCMPAL,‘9’JGNEXT2SUBAL,30HJMPSHORTNEXT3NEXT2:CMPAL,‘A’JLERRORCMPAL,‘F’•,37HNEXT3:ORDL,ALRORDX,CLDECCHJNZNEXT1MOVWORDPTRMBIN,DXMOVAH,4CHINT21HCODEENDSEDNBEGIN•[例4-20]把存放在BUFF中的16位二进制数转换为ASCII表示的等值数字字符串。例如FFFFH转换成等值的数字字符串‘65535’。DATASEGMENTBUFFDW4FB6HASCCDB5DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVCX,5LEADI,ASCCXORDX,DXMOVBX,0AH•:DIVBXADDDL,30HMOV[DI],DLJLERRORINCDIANDAX,AXJZSTOMOVDL,0LOOPAGAINSTO:MOVAX,4CHINT21HCODE
本文标题:4-4循环程序设计.
链接地址:https://www.777doc.com/doc-2922959 .html