《基本程序设计》PPT课件.ppt
第第5 5章章 基本程序设计基本程序设计第第5 5章章 基本程序设计基本程序设计 5.1顺序程序设计顺序程序设计5.2分支程序设计分支程序设计5.3循环程序设计循环程序设计5.4子程序设计子程序设计5.5具有模块结构的程序设计具有模块结构的程序设计第第5 5章章 基本程序设计基本程序设计5.1顺序程序设计顺序程序设计8086的汇编语言程序设计比较复杂,掌握它有一定的困难,故必须先掌握8086的指令系统及汇编语言的基本约定。从本章起,我们可以集中力量来解决程序设计的方法问题,并将编写的源程序进行汇编和连接,生成对应的可执行的程序文件,在MSDOS环境下运行这些程序,这将大大加快学习汇编语言的进程,深入掌握汇编语言程序设计的方法。第第5 5章章 基本程序设计基本程序设计任何一种程序设计语言编写的程序,其结构都是由顺序程序、分支程序和循环程序这三种基本结构组成的。程序结构设计方法简介。程序结构设计是把算法转化为程序的准备阶段。对于算法比较复杂的问题,应绘制程序结构图或程序流程图。结构图可描述各模块间的参数传送及相互调用的关系,程序流程图则能较好地描述程序执行的过程。第第5 5章章 基本程序设计基本程序设计1.结构图(structurechart)结构图是描述程序结构和程序模块间的关系的一种设计方法,它的基本部分是长方形框,每个框表示1个模块,如图所示。方框内用字符串表示(标记)模块的名字,方框之间的带方向的箭头连线表示模块间的调用关系。调用模块或外层模块通常画在上面,箭头指向的框表示被调用的模块或内层模块,图5.1(a)中,A框为调模块,B框为被调用模块。第第5 5章章 基本程序设计基本程序设计若可以选择性地调用,主模块以射线的形式表示,如图5.1(b)中,调用模块A可有选择地调用B,C及D模块。图5.1(c)则描述了在一个循环层中调用B,C,D模块的方式。图5.1(d),描述当两个模块间有信息交换时的情况,此时可用带标注的箭头来表示信息内容.第第5 5章章 基本程序设计基本程序设计图5.1结构图法示例第第5 5章章 基本程序设计基本程序设计2.流程图法(flowchart)流程图是最早被使用的一种方法,也是最直观的方法。流程图由逻辑框和流程线组成。逻辑框是指示程序的操作功能的符号,流程线是指示操作顺序的符号。流程图常用符号如图所示。第第5 5章章 基本程序设计基本程序设计图5.2流程图中的符号第第5 5章章 基本程序设计基本程序设计(1)端点框端点框表示程序的两端起点和终点。框内可以写上合适的文字,例如“开始(start)”,“结束(end)”或者程序名,起始地址等。(2)过程框或处理框用于表示一种处理功能或过程的程序段,框内可用文字标注扼要的功能或过程说明。该框可以简单到只包含一条指令,复杂到描述一个程序模块(或子程序即过程)。第第5 5章章 基本程序设计基本程序设计(3)判断框用于表示1个程序中判定点,程序将从这一点开始分支,框内用文字符号注明检测条件,而检测的结果分别注明于各分支流程线上。(4)连接框它表示1段程序在此处被人为中止,框内标有符号,以便与带有同样符号的另一个框相联系。对于一个大的流程图或由于篇幅不够、或由于避免出现交叉而不得不被打断的情况下,用连接框表示程序流程图从何处被中止,又从何处重新开始。第第5 5章章 基本程序设计基本程序设计(5)流程线带有箭头的流程线用于指出程序执行的流向。一个程序按其功能可分为若干部分,每部分可用一个逻辑框来表示,各个逻辑框通过流程线有机地联系起来,构成了总的程序流程图。流程图可以清楚地反映设计思想和程序结构是否合理。流程图是程序设计中使用得最早,最易为人们接受和应用的一种有效的工具。第第5 5章章 基本程序设计基本程序设计3.NS图(NASSISHCINDERMAN)NS图又称为方块图,是结构化程序设计中的算法描述工具。用NS图得到的程序一定是结构化程序。非结构化的程序,用NS图是无法表示的。它有三种基本逻辑,五种类型,如图所示。三种基本逻辑即顺序逻辑、选择逻辑和循环逻辑。选择逻辑可分为单分支和多分支两类。循环逻辑又分为当型循环(dowhile)和直到型循环(dountilp)两类。第第5 5章章 基本程序设计基本程序设计图5.3NS图表示法第第5 5章章 基本程序设计基本程序设计4.伪码流程图伪码流程图是通过形式语言描述程序结构的一种方法。它可以直接把流程图或方块图(NS图)以伪码流程图的形式表示出来,并能很方便地转化为程序。例如:选择结构可以表示如下:IFPTAELSEBENDIF第第5 5章章 基本程序设计基本程序设计对于多分支的选择结构可用伪码流程图表示如下:DOCASECASEP1ACASEP2BCASEPNSENDCASE第第5 5章章 基本程序设计基本程序设计5.1.1简单算术运算及逻辑运算顺序程序1.单字节压缩BCD数加法运算例5.1将存储单元A1和A2中的两个BCD数相加,结果送至A3单元中。相加后的进位送至A31单元。分析:为了得到十进制的结果,应在两个字节相加后再用加法十进制调整指令DAA进行调整。对于A1、A2、A3这三个存储器变量的存取方法,希能通过实例掌握。第第5 5章章 基本程序设计基本程序设计源程序如下:NAMEEX051DATASEGMENTA1DB48HA2DB53HA3DB2DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA第第5 5章章 基本程序设计基本程序设计START:MOVAX,DATAMOVDS,AXMOVAL,A1ADDAL,A2DAAMOVA3,ALLAHFANDAH,01HMOVA31,AHMOVAH,4CHINT21HCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计2.二进制字加法及乘法运算例5.2首先将FIRST字变量与SECOND字变量相加,结果存至THIRD存储字中,然后将FIRST与SECOND两个字变量相乘,结果存至THIRD1开始的两个字中。分析:8088的指令既可进行字节运算,也可进行字运算,只要变量类型定义正确,本程序即很容易编写。第第5 5章章 基本程序设计基本程序设计源程序如下:;NAMEEX052DATASEGMENTFIRSTDW7684SECONDDW23569THIRDDW?THIRD1DW2DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA第第5 5章章 基本程序设计基本程序设计START:MOVAX,DATAMOVDS,AXMOVAX,FIRSTADDAX,SECONDMOVTHIRD,AX;保存加法结果MOVAX,FIRSTMULSECONDMOVTHIRD1,AXMOVTHIRD12,DX;保存乘法结果MOVAH,4CHINT21H第第5 5章章 基本程序设计基本程序设计CODEENDSENDSTART其中MULSECOND实现16位乘法,即(AX)*存储器字,存储器变量给指令功能的灵活性发挥了很大的作用,使程序设计变得更加简单省事。第第5 5章章 基本程序设计基本程序设计3.取数的反码和补码例5.3将字变量A1转换为反码和补码,分别存入字变量A2和A3中。分析:此处的取反码和取补码,是指取一个数的相反数的反码和补码。取反码要求原数按位求反,可由NOT指令实现,补码可由反码加1得到。也可以由NEG指令获取相反数的补码,由补码减1得到反码值。所以可用两种方法来实现。第第5 5章章 基本程序设计基本程序设计(1)先取反,再取补的程序段:MOVAX,A1NOTAX;取反码MOVA2,AXINCAX;形成补码MOVA3,AX第第5 5章章 基本程序设计基本程序设计(2)先取补再取反的程序段:MOVAX,A1NEGAX;取补码MOVA3,AXDECAX;形成反码MOVA2,AX第第5 5章章 基本程序设计基本程序设计5.1.2字符处理和代码转换程序1.屏蔽和组合例5.4将字类型变量A的高4位和低4位置0,其余各位保持不变。分析:要让一个数的某几位置0,则只要与一个数相与。对应位为0,则相与结果即为0;对应位为1,则相与结果即保持不变。此处应与数0FF0H相与,0FF0H被称为屏蔽字。对应的程序段如下:第第5 5章章 基本程序设计基本程序设计MOVAX,AANDAX,0FF0HMOVA,AX也可用1条8086指令实现:ANDA,0FF0H;可见8086指令灵活、功能强大第第5 5章章 基本程序设计基本程序设计2.拆字例5.5将存储单元A中2个压缩BCD数拆成2个非压缩的BCD码,低位BCD数存入C中,高位BCD数存于B中,并将对应的ASCII码存入C1及B1中。分析:将1个字节中的两位BCD码分开,可采用屏蔽高4位、保留低4位的方法,得到低位BCD码;由未组合的BCD码转为ASCII码,只要高4位加或或30H;若将高4位BCD码分离,可以采用逻辑右移4位的方法,左边移入4个0,即可达到目的。程序段如下:第第5 5章章 基本程序设计基本程序设计程序段如下:NAMEEX055DATASEGMENTADB37HBDB?CDB?B1DB?C1DB?DATAENDSCODESEGMENT第第5 5章章 基本程序设计基本程序设计ASSUMECS:CODE,DS:DATAMAINPROCFARSTART:PUSHDSMOVAX,0PUSHAX;保存返回地址MOVAX,DATAMOVDS,AXMOVAL,AMOVCL,4SHRAL,CLMOVB,AL第第5 5章章 基本程序设计基本程序设计ORAL,30HMOVB1,ALMOVAL,AANDAL,0FHMOVC,ALORAL,30HMOVC1,ALRET;返回DOSMAINENDPCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计3.查表将1个09的BCD数转换成格雷码格雷码又称循环码,循环码的特点是任意两个相邻的数之间只有1位状态改变。即任意一个BCD数与它相邻的数之间只有1位(二进制位)的状态不同。满足这种要求的编码状态很多,表仅给出一种。第第5 5章章 基本程序设计基本程序设计表5.1格雷码与BCD数之间的对应关系第第5 5章章 基本程序设计基本程序设计例5.6将变量A中的两位BCD码转换为格雷码。高位格雷码存于C中,低位的格雷码存于B中。分析:查表指令XLAT是实现转换的关键,该指令要求从(DS):(BX)(AL)中取得结果。源程序如下:NAMEEX056DATASEGMENTGRAYDB00H,01H,03H,02H,06HDB0EH,0AH,08H,0CH,04H第第5 5章章 基本程序设计基本程序设计ADB25HBDB?CDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAL,AMOVCL,4SHRAL,CL第第5 5章章 基本程序设计基本程序设计MOVBX,OFFSETGRAYXLATMOVC,ALMOVAL,AANDAL,0FHXLATMOVB,ALMOVAH,4CHINT21HCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计5.2分支程序设计分支程序设计5.2.1简单分支结构程序单重分支程序的结构可用图表示。图中的T(true)表示条件为真(成立),F(false)表示条件为假(不成立)。在8088汇编中,条件判断和转移操作通常用比较指令和条件转移指令实现。比较指令根据比较结果置标志位,转移指令根据标志位决定分支的走向。第第5 5章章 基本程序设计基本程序设计图5.4单重分支结构程序第第5 5章章 基本程序设计基本程序设计例5.7变量X的符号函数可用下式表示:Y的取值是由X的符号决定的。为了判别X的符号,可以让X直接与0比较,也可以用一条能影响标志位的指令来进行。例如用与或或操作,就把X的符号和是否为0反映到SF与ZF标志上。流程图如图5.5所示。第第5 5章章 基本程序设计基本程序设计图5.5符号函数的程序流程图第第5 5章章 基本程序设计基本程序设计源程序如下:NAMEEX057CODESEGMENTASSUMECS:CODE,DS:CODESIGEF:PUSHCSPOPDS;将CODE值赋给DSMOVAX,X;取变量X值ORAX,AX;置标志JEZERO;X为0转ZERO第第5 5章章 基本程序设计基本程序设计JNSPLUS;X不为负,转PLUSMOVBL,0FFH;X为负,将0FFH(即-1)(BL)JMPCONTI;ZERO:MOVBL,0;X为0,将0(BL)JMPCONTIPLUS:MOVBL,1;X为正,将1(BL)CONTI:MOVRESULT,BL;保存结果至RESULTMOVAH,4CH;返回DOSINT21H第第5 5章章 基本程序设计基本程序设计XDW7086HRESULTDB?CODEENDSENDSIGEF该程序中,DS与CS都对应同一个逻辑段CODE,由于CODE由系统自动装入CS中,故用PUSHCS,先将CS值压入堆栈,然后再用POPDS指令,将CODE值装入DS。在CODE中除了指令代码外,还含有X和RESULT这样的数据变量。第第5 5章章 基本程序设计基本程序设计例5.8比较两个带符号数的大小,若AB,则显示出AB,否则显示BA。程序流程图如图所示。图5.6例5.8程序流程图第第5 5章章 基本程序设计基本程序设计源程序如下:NAMEEX058CODESEGMENTASSUMECS:CODE,DS:CODESTART:PUSHCSPOPDSMOVAL,ACMPB,ALJGEBGA;BA转BGAMOVDL,A;准备显示AB第第5 5章章 基本程序设计基本程序设计MOVAL,BJMPCOMBGA:MOVDL,B;准备显示BAMOVAL,ACOM:MOVAH,2;利用系统调用2,显示1个字符INT21HMOVDL,INT21HMOVDL,ALINT21H第第5 5章章 基本程序设计基本程序设计MOVAH,4CH;返回DOSINT21HADBBDBCODEENDSENDSTART此处利用系统调用2,显示比较的结果,要求将调用号2送入AH,显示的字符ASCII码送DL,用INT21H进行调用。第第5 5章章 基本程序设计基本程序设计5.2.2多分支结构程序在程序设计中,有时要求对多个条件同时进行判断,根据判断的结果,可能有多个分支要进行处理,就象伪码流程图法中的DOCASE语句及NS图表示法中的多分支逻辑结构。然而在汇编语言中,每一条条件转移指令只有两个出口,因此,在遇到多分支结构的程序时,只能用多条条件转移指令来实现。例5.9根据源块地址与目标块地址有无重叠分别用不同的方式进行数据块传送的指令。第第5 5章章 基本程序设计基本程序设计例如在A地址有50个单元的数据块,要求传到B地址处的50个单元的存储区中,A和B两个区域的位置关系,可有三种情况,如图所示。图5.7(a)为两个数据块之间没有重叠的情况,而图5.7(b)和(c),为两个数据块之间存在部分重叠的情况。对于图5.7(b),若由A块传送至B块,可采用由低地址端先传送,按增址方向实现字符串的自动传送。但不能采用由高地址端先传送,按减址方向实现字符串的自动传送。第第5 5章章 基本程序设计基本程序设计图5.7两数据块关系图第第5 5章章 基本程序设计基本程序设计对于图5.7(c),由A块传送至B块,则应采用从高地址端先传送,按减址方向重复字符串的传送,而不应由低地址端先传送,按增址方向重复字符串的传送。不注意以上的情况,并采取不同的传送方法,就可能在传送中破坏重叠区的原来数据。图5.8,就是能区别A、B两块间的位置关系,正确传送块的流程图。对应的源程序如下:第第5 5章章 基本程序设计基本程序设计图第第5 5章章 基本程序设计基本程序设计对应的源程序如下:NAMEEX-05-9DATASEGMENTBLOCKDB100DUP(X)DB100DUP(Y);定义了200个字节的存储区AEQUBLOCK20BEQUBLOCK60;A,B关系属图的(c)LEQU50第第5 5章章 基本程序设计基本程序设计DATAENDSSTACKSEGMENTPARASTACKSTACKDB100DUP(?)STACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,ES:DATA,SS:STACKSTARTPROCFARBEGIN:PUSHDS第第5 5章章 基本程序设计基本程序设计MOVAX,0PUSHAXMOVAX,DATAMOVDS,AXMOVES,AXMOVSI,OFFSETAMOVDI,OFFSETBCMPSI,DIJADOA;A为大地址,转DOA第第5 5章章 基本程序设计基本程序设计ADDSI,L1;取A尾址CMPSI,DI;A尾址B首址(无重叠?)JBDOA;A尾址小,无重叠STD;重叠,减量数据串传送ADDDI,L1;指向B串尾址JMPBMVDOA:CLDBMV:REPMOVSBRETSTARTENDSENDBEGIN第第5 5章章 基本程序设计基本程序设计5.3循环程序设计循环程序设计5.3.1循环程序的两种基本结构循环程序一般由以下三个部分组成:(1)循环体就是要求重复执行的程序段部分,又可以再细分为循环工作部分和循环控制部分。循环工作部分为要求被重复执行的程序段,它完成有关处理操作。循环控制部分在每次循环时都要检查一次循环的结束条件。当满足条件时就结束循环,继续往下执行其它程序段。第第5 5章章 基本程序设计基本程序设计(2)循环结束部分完成循环结束后的处理,如数据的分析、结果的存放等。(3)循环初始部分完成进行循环所作的准备工作,例如设置循环程序工作部分的有关地址指针、寄存器的初值、控制循环的条件或循环计数器的初始值设置以及有关标志值等。第第5 5章章 基本程序设计基本程序设计图与图分别为两种循环程序的基本结构。前者是先处理后判断的循环程序结构,其特点是循环体至少被执行一次;后者是先判断后处理的循环结构,其特点是循环工作部分可能一次也不执行。第第5 5章章 基本程序设计基本程序设计图5.9先处理后判断第第5 5章章 基本程序设计基本程序设计图5.10先判断后处理第第5 5章章 基本程序设计基本程序设计5.3.2用计数器控制的循环计数控制的循环是最常用的也是最普通的控制循环的方法。下面通过若干个例子进行介绍。例5.10在一串给定个数的存储区中寻找最大值,并放至指定的存储单元,每个数用16位表示。现假设串中数据的个数存于COUNT单元,数据从BUFF单元开始存放,最大值求出后保存在MAX单元中。源程序如下:NAMEEX-05-10DATASEGMENT第第5 5章章 基本程序设计基本程序设计BUFFDWX1,X2,XNCOUNTDW$-BUFFMAXDW?DATAENDSSTACKSEGMENTPARASTACKSTACKSTACK1DB-100DUP(?)TOPEQU$-STACKSTACKENDSCODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK第第5 5章章 基本程序设计基本程序设计STARTPROCFARBEGIN:PUSHDSMOVAX,0PUSHAXMOVAX,DATAMOVDS,AXMOVAX,STACKMOVSS,AX;设置堆栈段基址MOVAX,TOPMOVSP,AX;设置堆栈SP初值第第5 5章章 基本程序设计基本程序设计MOVCX,COUNTLEABX,BUFFMOVAX,BXINCBXINCBXDECCXAGAIN:CMPAX,BXJGENEXTMOVAX,BX第第5 5章章 基本程序设计基本程序设计NEXT:INCBXINCBXLOOPAGAINRETSTARTENDPCODEENDSENDBEGIN程序中的$表示当前单元计数器的值,$-BUFF表示BUFF定义的存储区中字的个数减去起始地址,这个值刚好就是数据字的个数N。第第5 5章章 基本程序设计基本程序设计$-STACK,现在是字节单元个数100,将它赋给TOP,实际上它就是堆栈栈顶元素的段内偏移量,MOVAX,TOP和MOVSP,AX,将TOP赋给了SP,完成堆栈的设置。例5.11统计正数、负数和零的个数。要求对BUFF开始的存储区中存放的一组带符号数,统计其正数的个数、负数的个数和零的个数并存于PLUS、MINUS及ZERO单元。第第5 5章章 基本程序设计基本程序设计图5.11例5.11程序流程图第第5 5章章 基本程序设计基本程序设计源程序如下:NAMEEX-05-11DATASEGMENTBUFFDB2,-3,18,-24,NEQU$-BUFFPLUSDB?MINUSDB?ZERODB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA第第5 5章章 基本程序设计基本程序设计START:MOVAX,DATAMOVDS,AXMOVSI,OFFSETBUFFMOVCX,NMOVDL,0;DL为正数计数器MOVDH,DL;DH为负数计数器MOVBL,DL;BL为零个数计数器LOP:CMPBYTEPTRSI,0JECZERO;若为0,零个数计数器加1JGCPLUS;若为正数,正数计数器加1第第5 5章章 基本程序设计基本程序设计INCDH;若为负数,负数计数器加1JMPNEXTCZERO:INCBLJMPNEXTCPLUS:INCDLNEXT:INCSILOOPLOPNZERO:MOVPLUS,DLMOVMINUS,DHMOVZERO,BL第第5 5章章 基本程序设计基本程序设计MOVAH,4CHINT21HCODSENDSENDSTART在统计时,直接对PLUS、MINUS和ZERO单独使用INC指令也是可以的,但这样做,三存储单元的初值应为0。对BUFF单元,用DW定义,就成为统计字类型的带符号数的程序。在INCSI后,再插入一条INCSI指令,以保证每次统计后,指针要移动两个单元。第第5 5章章 基本程序设计基本程序设计例5.12数据传送程序。将BUFF1开始的存储区中的20个字节的数据传送到BUFF2开始的存储区中,且不考虑数据块的重叠问题。分析:由于数据块的长度已知,因此可用计数控制的循环程序来实现。每传送一个字节,应修改源块和目标块的地址指针,计数值减1为0时,循环结束。源程序如下:NAMEEX-05-12DATASEGMENTBUFF1DB0,1,2,3,4,5,6,7,8,9,10,11,12第第5 5章章 基本程序设计基本程序设计DB13,14,15,16,17,18,19BUFF2DB20DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVCX,20LEASI,BUFF1LEADI,BUFF2第第5 5章章 基本程序设计基本程序设计CYCLE:MOVAL,SIMOVDI,ALINCSIINCDILOOPCYCLEMOVAH,4CHINT21HCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计例5.13考虑数据块重叠的传送数据块程序。这里设源块首址低于目标块首址,但并不知道这两块是否有重叠,因此需要判别。若无重叠,则按地址升序进行传送;若有重叠,则应从末地址开始,减址方向进行传送。源程序如下:NAMEEX-05-13DATASEGMENTSTRGDBABCDEFGHIJKLMNOPSTRG1EQUSTRG+4STRG2EQUSTRG+8STRLNEQU6第第5 5章章 基本程序设计基本程序设计DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVCX,STRLNMOVSI,OFFSETSTRG1MOVDI,OFFSETSTRG2PUSHSIADDSI,STRLN-1;SI指向源块末地址第第5 5章章 基本程序设计基本程序设计CMPSI,DIPOPSIJLMOVINC;无重叠,转MOVINC,按增址顺序传送ADDSI,STRLN-1;重叠时,SI,DI指向末地址ADDDI,STRLN-1;进行减址传送MOVDEC:MOVAL,SIMOVDI,ALDECSIDECDI第第5 5章章 基本程序设计基本程序设计LOOPMOVDECJMPDONEMOVINC:MOVAL,SIMOVDI,ALINCSIINCDILOOPMOVINCDONE:MOVAH,4CHINT21HCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计5.3.3条件控制的循环程序有些循环程序的循环次数是不知道或不确定的,因此需要根据某些条件来确定是否结束循环。例如统计一个字符串的长度,由于事先不知道串的长度,因此这是一个循环次数未知的循环程序。如果知道这个串以什么字符结束,例如以$或0DH或其它已知的字符结束时,我们便以检测是不是这个字符来决定循环的结束。第第5 5章章 基本程序设计基本程序设计例5.14统计字符串长度。要求从STRN地址起的一串字符进行统计,求其串长,串尾以$结束,且串长不包含$。分析:为了统计字符个数,需要指定一个累加器,且事先应清0,以后每统计一个字符,累加器便加1,直至取出的字符为$时为止。源程序如下:NAMEEX-05-14DATASEGMENTSTRNDBABCDRA,$第第5 5章章 基本程序设计基本程序设计STRLNDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETSTRNMOVDL,0;DL中为串长AGAIN:MOVAL,SICMPAL,$;串尾为$否?第第5 5章章 基本程序设计基本程序设计JEDONEINCDLINCSIJMPAGAINDONE:MOVSTRLN,DLADDDL,30H;设字符个数小于10MOVAH,02INT21H;将字符个数显示出来MOVAH,4CHINT21HCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计例5.15要求统计串中的空格个数和逗号的个数。空格的ASCII码为20H,逗号的ASCII码为2CH。设该串仍以$字符结尾,此时,应设两个计数器,例如:DH为空格计数器,DL为,的计数器。源程序如下:NAMEEX-05-15DATASEGMENTSTRNDBAabcdBE,RES,$SPCLNDB?DELILNDB?DATAENDSCODESEGMENT第第5 5章章 基本程序设计基本程序设计ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETSTRNMOVDX,0AGAIN:MOVAL,SICMPAL,$;判断串尾为$JEDONECMPAL,20H;判有没有空格JNENEXT第第5 5章章 基本程序设计基本程序设计INCDHJMPCONTINEXT:CMPAL,2CH;判有没有逗号JNECONTIINCDLCONTI:INCSIJMPAGAINDONE:MOVSPCLN,DH;存空格数第第5 5章章 基本程序设计基本程序设计MOVDELILN,DL;存逗号数MOVAH,4CHINT21HCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计5.3.4用逻辑尺控制的循环在一个循环内部可能有两个分支,每一个分支可能是一个不同功能的程序段,在整个程序执行时,第一个分支与第二个分支按照一定的次序轮流执行。因此,可以把规定执行的次序设置在一个逻辑尺中,用以控制转入不同的支路执行。例如该位为0,转入第一个分支;该位为1,转入第二个分支执行。第第5 5章章 基本程序设计基本程序设计例5.16设有两个子程序,第一个为FUN1,第二个为FUN2,可以完成对一个部件的加工操作。其操作顺序是执行二次FUN2,接着执行二次FUN1,再执行三次FUN2。分析:若逻辑尺某位为1,执行FUN2;为0执行FUN1,则逻辑尺可设置为1100111B,循环总次数为7。工作时,将逻辑尺逐位移入CF位,然后对CF进行判别。源程序如下:NAMEEX-05-16CODESEGMENTASSUMECS:CODE第第5 5章章 基本程序设计基本程序设计C1EQU7C2EQU11001110BSTART:MOVCL,C1MOVAL,C2LP:SALAL,1;将逻辑尺某位移至标志位JCR2CALLFUN1;执行FUN1子程序CM:DECCL;循环总次数减1JNZLPMOVAH,4CH第第5 5章章 基本程序设计基本程序设计INT21HR2:CALLFUN2;执行FUN2子程序JMPCMFUN1PROCRETFUN2PROCRETCODEENDSENDSTART第第5 5章章 基本程序设计基本程序设计5.4子程序设计子程序设计5.4.1子程序与主程序一般把调用子程序的程序称为主程序,也称为调用程序,而在程序中被多次调用的程序称为子程序。主程序与子程序是相对而言的,因为子程序又可以再调用另一个子程序,这种情况称为子程序的嵌套。如图所示,主程序是通过调用指令CALL来调用子程序的。第第5 5章章 基本程序设计基本程序设计图5.12主程序和子程序的调用关系第第5 5章章 基本程序设计基本程序设计5.4.2子程序的段内调用和返回对于近类型的子程序,可直接在代码段定义,此时调用程序与子程序处于同一个段内。若有多个子程序,均可在代码段中定义它们。这时,调用程序可以在子程序的前面,也可以在子程序的后面,但是不允许调用程序和子程序交叉存放。第第5 5章章 基本程序设计基本程序设计例5.17编写一个程序,从键盘键入一个字符,若为F,则调用FIRST子程序;若为S,则调用SECOND子 程 序,否 则 显 示 INPUT CHARACTERFORS!返回DOS。FIRST和SECONT子程序为近过程。1.主程序在子程序的前面NAMEEX-05-17DATASEGMENTSTR0DBINPUTCHARACTERFORS!,$STR1DBINPUTCHARACTER:$第第5 5章章 基本程序设计基本程序设计STR2DBTheFirstSubroutine!$STR3DBTheSecondSubroutine!$DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARSTART:PUSHDSMOVAX,0PUSHAX第第5 5章章 基本程序设计基本程序设计MOVAX,DATAMOVDS,AXMOVDX,OFFSETSTR1MOVAH,09HINT21H;提示输入字符MOVAH,01HINT21HCMPAL,FJESUBF;为F调用子程序FIRSTCMPALSJESUBS;为S调用子程序SECOND第第5 5章章 基本程序设计基本程序设计CALLENTERLEADS,STR0MOVAH,09HINT21H;提示输入字符形式JMPRETNSUBF:CALLFIRSTJMPRETNSUBS:CALLSECONDRETN:RETMAINENDP第第5 5章章 基本程序设计基本程序设计ENTERPROCMOVDL,0DHMOVAH,02HINT21HMOVDL,0AHMOVAH,02INT21H;完成回车换行RETENTERENDPFIRSTPROCCALLENTER第第5 5章章 基本程序设计基本程序设计LEADS,STR2MOVAH,09HINT21HRETFIRSTENDPSECONDPROCCALLENTERLEADS,STR3MOVAH,09HINT21HRET第第5 5章章 基本程序设计基本程序设计SECONDENDPCODEENDSENDSTART在以上程序中,其中MAIN为主程序,放在代码段的最前面还定义了四个子程序。ENTER子程序为公用子程序,其作用是完成光标的回车换行。FIRST子程序、SECOND子程序及MAIN主程序都调用了ENTER子程序。只要在END语句中,指向主程序的START,那么在程序装入内存执行时,总是先转入主程序执行。第第5 5章章 基本程序设计基本程序设计2.主程序在子程序的后面以上程序也可将主程序MAIN安排在三个子程序的后面,即在ASSUME伪指令后面,分别定义ENTER、FIRST及SECOND三个子程序,最后定义MAIN主程序,只要程序在结尾处,用ENDSTART即可。此处不再列出程序。第第5 5章章 基本程序设计基本程序设计5.4.3子程序段间调用和返回子程序如果用于段间调用,那么在过程定义时就应将它定义为FAR类型。在调用FAR类型的子程序时,CALL指令所完成的操作与段内调用时不同,CALL指令在汇编时产生的机器代码也不相同,以保证段间调用时,不仅要保存返回地址的段内偏移量,而且要保存返回地址的段基址。第第5 5章章 基本程序设计基本程序设计1.同一模块内的段间调用例5.18编写一个主程序,从键盘输入二位非压缩的BCD数,存入AX寄存器中。为了将其转换为二进制数,应编写一个远类型的子程序。若将字符显示出来,可用近类型子程序实现,也可用远类型子程序实现。主程序执行时,数据可循环输入,遇到00结束。由于显示子程序既可被调用程序调用,又可被转换程序调用,故也定义为远类型。主程序MAIN通过系统调用1,从键盘输入两个BCD数的ASCII码,存于AX中。若是00,则返回DOS,否则调用转换程序进行转换。第第5 5章章 基本程序设计基本程序设计转换程序TRAN完成将BCD码转换为二进制数。显示程序CON,主要完成将十六进制数转换为对应的ASCII码送入AL中,然后调用显示子程序DISP,显示该字符。TRAN子程序流程图如图所示。一位十六进制数转换为ASCII码流程图如图所示。第第5 5章章 基本程序设计基本程序设计图5.13TRAN子程序流程图第第5 5章章 基本程序设计基本程序设计第第5 5章章 基本程序设计基本程序设计图5.14一位十六进制数转为ASCII码流程图第第5 5章章 基本程序设计基本程序设计整个程序如下:NAMEEX-05-18STASEGMENTSTACKSTACKDB100DUP(0)STAENDSCSAGSEGMENTPARACODEASSUMECS:CSAG,SS:STAMAINPROCFARSTART:PUSHDSSUBAX,AXPUSHAX第第5 5章章 基本程序设计基本程序设计REV:MOVAH,1INT21HMOVBL,ALINT21HMOVAH,ALMOVAL,BL;AX中为键入的两位BCD的ASCII码CMPAX,3030H;判AX中是否为00JEENDTRANCALLNEARPTRTRANCALLFARPTRCONMOVAL,0DH第第5 5章章 基本程序设计基本程序设计CALLFARPTRDISPMOVAL,0AHCALLFARPTRDISPJMPREVENDTRAN:RETMAINENDPTRANPROCNEARANDAX,0F0FH;将ASCII码转换为非压缩的BCD码MOVBL,AL;高位BCD在AL中MOVCL,3SHLAL,CL第第5 5章章 基本程序设计基本程序设计MOVCL,1SHLBL,CLADDAL,BL;完成高位BCD数乘10ADDAL,AH;将两位BCD数转为二进制数RETTRANENDPCSBGSEGMENTPARACODEASSUMECS:CSBGCONPROCFARPUSHAX第第5 5章章 基本程序设计基本程序设计MOVCL,4SHRAL,CL;将AL高4位移至低4位ADDAL,30HCMPAL,39HJBECON2;为小于等于9的BCD数转CON2ADDAL,7CON2:PUSHAXMOVAL,0DHCALLFARPTRDISPMOVAL,0AH第第5 5章章 基本程序设计基本程序设计CALLFARPTRDISPPOPAXCALLFARPTRDISP;显示高位十六制数POPAXANDAL,0FHADDAL,30HCMP