《第四章程序流程控制语句及程序设计.ppt》由会员分享,可在线阅读,更多相关《第四章程序流程控制语句及程序设计.ppt(80页珍藏版)》请在课桌文档上搜索。
1、1,第4章 程序设计的基本方法,4.1 程序设计方法概述4.2 顺序程序设计4.3 分支程序设计 4.4 循环程序设计4.5 子程序设计4.6 程序设计中的注意事项,开始,2,4.1 概述,4.1.1 汇编语言程序设计的一般步骤4.1.2 流程图,返回本章首页,3,4.1.1 汇编语言程序设计的一般步骤,汇编语言程序设计一般有以下几个步骤:1、分析问题,确定算法2、根据具体问题,确定输入输出数据的格式3、分配存储区并给变量命名(包括寄存器)4、绘制流程图5、根据流程图编制程序6、调试程序,返回本节,4,4.1.2 流程图,1流程图的概念流程图是由特定的几何图形、指向线、文字说明来表示数据处理的
2、步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。,2流程图符号表示(1)起止框:表示程序的开始和结束。,起止框,5,(2)判断框,(3)处理框,(4)调用框,(5)指向线,(6)连接框,返回本节,6,4.2 顺序程序设计,顺序程序流程图组成:只有一个起始框、一个终止框和一至几个处理说明框。【例4.1】从键盘上输入0至9中任一自然数x,求其立方值。解题方法:采用构造一立方表,运行时查表实现。输入输出数据格式:输入:0-9任一自然数,字节单元存储 输出:输入数的立方数,字单元存储分配存储区:字节变量X:存放键入自然数x 字变量XXX:存放x的立方值 变量TAB:假
3、定立方表的首地址(TAB+2*x)=x的立方值,TAB,7,流程图:,开始,输入数字x,将x真值放入X,查表得x立方放入XXX,结束,8,STACK SEGMENT STACK DB 200 DUP(0)STACK ENDSDATASEGMENT INPUT DB PLEASE INPUT X(09):$TAB DW 0,1,8,27,64,125,216,343,512,729 X DB?XXX DW?DATAENDS,编程,9,CODESEGMENTASSUME DS:DATA,CS:CODE,SS:STACKBEGIN:MOV AX,DATA MOV DS,AX MOV DX,OFFSE
4、T INPUT MOV AH,9 INT 21H MOV AH,1 INT 21H AND AL,0FH MOV X,AL,显示输入提示符,接受键盘输入数字x放入AL,求x的真值放入X,10,ADD AL,AL MOV BL,AL MOV BH,0 MOV AX,TABBX MOV XXX,AX MOV AH,4CH INT 21H CODE ENDS END BEGIN,2*xBX,查表TAB+BX放入XXX,返回本章首页,11,4.3 分支程序设计,4.3.1 控制转移类指令4.3.2 分支程序设计,返回本章首页,12,4.3.1 控制转移类指令,1、条件转移指令2、无条件转移指令,返回本
5、章首页,无条件转移指令和条件转移指令区别:1、前者转移是无条件的,而后者有;2、前者转移范围不受限制,而后者只能在-128127个字节范围内转移。,13,简单条件转移指令 无符号数条件转移指令 有符号数条件转移指令 语句格式:标号:操作符 短标号短标号:即当前(IP)到某标号(即转移的目的地址)的位移量在-128127间。功能:如果条件满足,则(IP)位移量IP。,1、条件转移指令,返回本节,14,共有10条指令,根据五个标志位ZF、SF、OF、PF和CF的两种状态(0或1)分别进行转移。(1)JE/JZ;ZF=1则转移,测试前次操作结果是否等于0 JNE/JNZ;ZF=0则转移,测试前次操作
6、结果是否不等于0(2)JS;SF=1则转移,测试前次操作结果是否为负数 JNS;SF=0则转移,测试前次操作结果是否为正数(3)JO;OF=1则转移,测试前次操作结果是否有溢出 JNO;OF=0则转移,测试前次操作结果是否没有溢出(4)JC;CF=1则转移,测试前次操作结果是否有进(借)位 JNC;CF=0则转移,测试前次操作结果是否无进(借)位,简单条件转移指令,15,(5)JP;PF=1则转移,测试前次操作结果中1的个数是否为偶数 JNP;PF=0则转移,测试前次操作结果中1的个数是否为奇数例:下面程序段测试AX的低四位是否全0,如果均是0,那么使CX=0,否则使CX=-1。MOV CX,
7、-1 TEST AX,000FH JNZ NEXT MOV CX,0 NEXT:,16,无符号数条件转移指令,无符号数条件转移指令往往跟在比较指令之后,根据运算结果设置的条件标志状态确定转移方向。这类指令视比较对象为无符号数。(1)JA/JNBE;高于/不低于且不等于转移。转移条件:当CF=0且ZF=0时转移。(2)JAE/JNB;高于或等于/不低于转移。转移条件:当CF=0或ZF=1时转移。(3)JB/JNAE;低于/不高于且不等于转移。转移条件:当CF=1且ZF=0时转移。(4)JBE/JNA;低于或等于/不高于转移。转移条件:当CF=1或ZF=1时转移。,17,【例4.5】比较AX、BX
8、中无符号数大小,将较大的数存放AX寄存器。CMPAX,BX;(AX)(BX)JAENEXT;若AX=BX,转移到NEXT XCHGAX,BX;若AXBX,交换 NEXT:,18,有符号数条件转移指令,当比较判断两个有符号数的大小时,要选用有符号数条件转移指令。有符号数条件转移根据条件标志ZF、SF、OF的特定组合决定是否转移。(1)JG/JNLE;大于/不小于且不等于转移。转移条件:当SF=OF且ZF=0时转移。(2)JGE/JNL;大于或等于/不小于转移。转移条件:当SF=OF或ZF=1时转移。(3)JL/JNGE;小于/不大于且不等于转移。转移条件:当SF OF且ZF=0时转移。(4)JL
9、E/JNG;小于或等于/不大于转移。转移条件:当SF OF或ZF=1时转移。,19,【例4.6】比较AX、BX中有符号数大小,将较大的数存放在AX寄存器。CMPAX,BX;(AX)(BX)JGENEXT;若AX=BX,转移到NEXT XCHGAX,BX;若AXBX,交换 NEXT:,20,2、无条件转移指令,用途:在分支语句中常用于将各分支出口重新汇集到一起。段内转移:指在同一代码段的范围内进行转移,只需要改变IP寄存器的内容。(1)段内直接转移格式:JMP 标号名;该标号的属性为近标号例如:JMP NEXT;(2)段内间接转移格式:JMP OPD;将OPD的内容送IP寄存器例如:JMP WO
10、RD PTR 1234H;将字存储单元1234H中的内容送IP寄存器,21,段间转移:指要转移到另一个代码段去执行程序,此时不仅需要改变IP寄存器中的内容,还要修改CS段寄存器的内容才能达到转移的目的,因此段间转移需要修改两个寄存器中的内容。(1)段间直接转移格式:JMP 标号名;该标号的属性为远标号(2)段间间接转移格式:JMP OPD;(OPD)IP,(OPD+2)CS例如:JMP DWORD PTR 1234H;将双字存储单元的低字内容送IP寄存器,双字存储单元的高字内容送CS寄存器,返回本节,22,4.3.2 分支程序设计,【例4.7】编写计算下面函数值的程序:1X0Y=0X=0-1X
11、0设输入数据为X、输出数据Y,且皆为字节变量。程序流程图如图4.2所示。程序如下:,23,图4.2 分支运算程序流程图,24,DATASEGMENTX DB-10Y DB?DATAENDSSTACKSEGMENT STACK DB 200 DUP(0)STACKENDSCODESEGMENTASSUME DS:DATA,SS:STACK,CS:CODESTART:MOVAX,DATA,25,MOVDS,AX CMPX,0;与0进行比较 JGEA1;X0转A1 MOVY,-1;X 0时,-1Y JMPEXITA1:JGA2;X0转A2 MOVY,0;X=0时,0Y JMPEXITA2:MOVY,
12、1;X0,1Y EXIT:MOVAH,4CH INT21H CODE ENDS ENDSTART,26,【例4.8】试编一程序,求三个带符号字数据中的最大值,并将最大值存入MAX字单元中。设三个带符号数分别在三个字变量X、Y、Z中存储。程序流程图如图4.3所示,27,图4.3例4.8程序流程图,28,程序如下:STACK SEGMENT STACK DB 200 DUP(0)STACK ENDSDATA SEGMENTX DW 00ABHY DW 5Z DW 200MAX DW?DATA ENDSCODE SEGMENTASSUME DS:DATA,SS:STACK,CS:CODE START
13、:MOV AX,DATA MOV DS,AX,29,MOV AX,X CMP AX,Y;XY?JG L1 MOV AX,Y;YZ?CMP AX,Z JG EXITL2:MOV AX,Z JMP EXITL1:CMPAX,Z;XZ?JLE L2EXIT:MOVMAX,AX MOVAH,4CH INT21HCODE ENDS END START,30,分支程序设计注意事项:1、选择合适的转移指令,否则就不能转移到预定的程序分支;2、要为每个分支安排出口,否则易导致程序运行的混乱;3、应把各分支中的公共部分尽量提到分支前或分支后的公共程序段中,使程序简洁、清晰;4、在分支比较多时,流程图中对每个分支
14、判断的先后次序应尽量与问题提出的先后次序一致;5、在调试分支程序时,要假定各种可能的输入数据,沿着每一支路逐一检查,测试程序是否正确。,返回本节,31,4.4 循环程序设计,循环指令4.4.1 循环程序的结构4.4.2 单重循环程序设计4.4.3 多重循环程序设计,返回本章首页,32,1)循环指令LOOP2)相等/为零循环指令LOOPE/LOOPZ3)不相等/不为零循环指令LOOPNE/LOOPNZ,循环指令(不改变标志位),33,1计数循环指令LOOP语句格式:LOOP 短标号功能:寄存器CX的值减1后,其结果不等于0,则转移到短标号;否则,顺序执行。说明:使用LOOP指令可代替两条指令,D
15、EC CX JNE 短标号,34,2相等/全零循环指令LOOPE/LOOPZ语句格式:LOOPE 短标号 LOOPZ 短标号功能:寄存器CX的值减1后0且ZF=1,则程序转移到短标号;否则,顺序执行。,35,分析下面的例子,该程序完成什么功能?DATA SEGMENT BUF DB AAABBCD COUNT EQU$-BUFDATA ENDS MOV AL,A MOV DI,OFFSET BUF MOV CX,COUNT DEC DINEXT:INC DI CMP AL,DI LOOPE NEXT MOV BX,DI JNZ EXIT MOV BX,0FFFFH;EXIT:.,36,功能:在
16、字符串查找是否存在非A字符,若找到,将BX指针指向第一个非A字符,否则置BX为-1。,注意:有两种可能退出循环的执行。(1)计数结束(CX)=0,此时ZF=1,表示所有都是A字符。(2)ZF=0,表示找到非A字符。,37,3不相等/不为零循环指令LOOPNE/LOOPNZ语句格式:LOOPNE 短标号 LOOPNZ 短标号功能:寄存器CX的值减1后0且ZF=0,则程序转移到短标号;否则,顺序执行。,返回本节,38,4.4.1 循环程序的结构,1初始化部分2工作部分3修改部分4.控制部分,39,循环程序的常见结构形式如图4.5(a)、(b)所示。,返回本节,40,4.4.2 单重循环程序设计,常
17、见的两种循环控制方式:1计数控制 2条件控制,循环体内不再包含循环结构的循环结构称为单重循环。,返回本节,41,1计数控制,【例4.10】已知有COUNT个字节数据存放在以BUF为首址的存贮区中,编写程序统计负数和正数的个数分别送MINUS和PLUS单元。算法设计:用DL和BL分别统计正数和负数的个数,初值为0。将BUF区中的n个数逐次取出,判断其值是否大于等于0,若是,则DL加1,否则BL加1,最后将BL送到MINUS,将DL送到PLUS。,对于循环次数已知的情况,通常采用计数控制方法来实现循环。又分为倒计数法和正计数法。,42,存储器分配:BUF:存放n个有符号数COUNT:存放有符号个数
18、nMINUS:存放负数个数PLUS:存放正数个数寄存器分配:BL:暂存负数个数,初值为0DL:暂存正数个数,初值为0SI:BUF地址指针,初值指向BUFCX:循环计数器,初值为COUNTAL:暂存从BUF中取出待判断正负属性的数。,43,DATA SEGMENT BUF DB-32,25,36,-18,-46,0,-3 COUNT EQU$-BUF PLUS DB?MINUS DB?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV BL,0;统计负数个数的计数器 MOV DL,0;统计正数个数
19、的计数器 MOV SI,OFFSET BUF MOV CX,COUNT,44,LOP1:MOV AL,SI CMP AL,0;判断是否为正数 JGE NEXT0 INC BL;若为负数,(BL)+1(BL)JMP NEXT1NEXT0:INC DL;若为正数,(DL)+1(DL)NEXT1:INC SI LOOP LOP1 MOV MINUS,BL MOV PLUS,DL MOV AH,4CH INT 21HCODE ENDS END START,45,2条件控制,【例4.11】已知在以PROG为首址的字节存储区中存放着一段汇编源程序,最后以Ctrl-z(其ASCII码为1AH)作为结束标志。
20、试编写程序,统计MOV的出现次数,并将统计结果送入字变量NUM之中。(P110例4)算法分析:从第一个字符开始,查找字符M,找到M后,查看其后是否是OV,若是,便是MOV的一次出现,故计数一次,并跳过OV,若不是,则不计数,然后从下一个字符开始再找MOV。如此循环,直到遇到串尾的结束标志(Ctrl-z)寄存器分配:SI:PROG存储区的地址指针,初值指向PROG AX:用来记录MOV出现的次数,初值为0,对于循环次数未知的情况,通常采用条件控制方法来实现循环。,46,STACK SEGMENT STACK DB 200 DUP(0)STACK ENDS DATA SEGMENT PROG DB
21、 MOV AX,DATA,0DH,MOV DS,AX,0DH,MOV AX,0,0DH DB MOV BX,2,0DH,MOV CX,10,0DH,ADD AX,BX,0DH DB DB 1AH NUM DW 0DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK,47,BEGIN:MOV AX,DATA MOV DS,AX MOV AX,0 MOV SI,OFFSET PROG LOPA:CMP SI,BYTE PTR 1AH JE EXIT CMP SI,BYTE PTR M JNE NEXT CMP SI+1,BYTE PTR O J
22、NE NEXT CMP SI+2,BYTE PTR V JNE NEXT INC AX ADD SI,2 NEXT:INC SI JMP LOPA,EXIT:MOV NUM,AX MOV AH,4CH INT 21HCODE ENDS END BEGIN,48,【例4.12】已知若干个非0整数a1,a2,a3,存放在以A为首址的字存储区中,末尾以0作为这组数的结束标志。现要求将其中的负数抹掉,而把留下的正数仍连续地重新存储在以A为首址的字存储区中,并把结束标志改为-1,试编写程序。(P112例5)算法分析:从表中取一元素,检查其值是否为0。如果是结束标志,说明表中元素已处理完毕,则结束循环;如
23、果不是结束标志,则对元素进行处理,判断其值是为正还是为负。若为正,则将其送入重新组成的正数表中,然后开始下一次循环,处理下一个元素;若为负,则不做任何处理,立即开始下一次循环。,49,寄存器分配:SI:作为从原始表中取数的地址指针,初值指向A,每取出一个数后,其值增2;BX:作为往新表中送数的地址指针,初值指向A,每送入一个数之后,其值增2;AX:用来存放待处理的元素ai。STACK SEGMENT STACK DB 200 DUP(0)STACK ENDS DATA SEGMENT A DW-1,2,3,-2,4,-333,-5,444 DW 600,755,-44,-60,-55,86,7
24、75,555 DW 100,200,300,400,-300,-400,-500 DW 432,32767,-32768,879,0 DATA ENDS,50,CODE SEGMENT ASSUME CS:CODE,SS:STACK,DS:DATABEGIN:MOV AX,DATA MOV DS,AX LEA SI,A MOV BX,SI LOPA:MOV AX,SI OR AX,AX JZ EXIT JS NEXT MOV BX,AX ADD BX,2NEXT:ADD SI,2 JMP LOPAEXIT:MOV BX,WORD PTR-1 MOV AH,4CH INT 21HCODE END
25、S END BEGIN,51,4.4.3 多重循环程序设计,如果一个循环程序的循环体内还包含一个或多个循环结构的程序,那么这个程序称为双重或多重循环结构程序。,【例4.13】在以BUF为首址的字节存储区中存放有n个无符号数X1,X2,Xn,现要求将它们按从小到大的顺序排列在BUF存储区中,试编写程序。P118例2,52,算法设计:采用冒泡法。首先将第一个元素与其它所有元素比较,若前者比后者小则交换位置,最后将第一个元素置换为最小值;然后将第二个元素与其后的所有元素比较得到次小值。依此类推,直到所有元素从小到大排列。寄存器分配:SI:用来存放i的值,初值为1,每外循环一次后增1,范围:1-(n-
26、1)DI:用来存放j的值,初值为i+1,每内循环一次后增1,范围:(i+1)-nAL:用来存放Xi,53,STACK SEGMENT STACK DB 200 DUP(0)STACK ENDSDATA SEGMENT BUF DB 30H,10H,40H,20H,0FFH N=$-BUFDATA ENDSCODE SEGMENT ASSUME CS:CODE,SS:STACK,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV SI,1;1(SI),54,LOPI:MOV DI,SI INC DI;(SI)+1(DI)MOV AL,BUF+SI-1LOPJ:CMP A
27、L,BUF+DI-1 JBE NEXT XCHG BUF+DI-1,AL MOV BUF+SI-1,ALNEXT:INC DI CMP DI,N JBE LOPJ INC SI CMP SI,N-1 JBE LOPI,55,MOV AH,4CH INT 21H CODE ENDS END START,返回本节,思考:如何实现从大到小的顺序排列。,56,4.5 子程序设计,4.5.1 子程序的概念4.5.2 子程序的定义4.5.3 子程序设计方法4.5.4 子程序应用举例4.5.5 子程序的嵌套,返回本章首页,57,4.5.1 子程序的概念,在程序设计中,我们会发现一些多次无规律重复的程序段或语
28、句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用,这样独立的程序段称为子程序。在汇编语言中,子程序又称过程。调用子程序的程序称为主调程序或主程序。,返回本节,58,4.5.2 子程序的定义,子程序的定义是由过程定义伪指令PROC和ENDP来完成的。其格式如下:过程名 PROC NEAR 过程名 PROC FAR 过程名 ENDP 过程名 ENDP 其中PROC表示过程定义开始,ENDP表示过程定义结束。过程名是过程入口地址的符号表示。一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性。,返回本节,59,4.5.3 子程序
29、设计方法,1.子程序的调用和返回2现场的保护与恢复3主程序与子程序参数传递方式,返回本节,60,1、子程序的调用和返回,子程序的调用:(1)段内直接调用格式:CALL PROC_NAME功能:(IP)(SP)目的地址EAIP(2)段间直接调用格式:CALL FAR PTR PROC_NAME功能:(CS)(SP),目的地址的段首址CS(IP)(SP),目的地址EAIP,61,(3)段内间接调用格式:CALL WORD PTR OPD功能:(IP)(SP)(OPD)IP(4)段间间接调用格式:CALL DWORD PTR OPD功能:(CS)(SP),(OPD+2)CS(IP)(SP),(OPD
30、)IP注意:本节例题均采用段内直接调用。,62,子程序返回指令RET语句格式1:RET功能:若是段间返回,则其操作为:(SP)IP(SP)CS 若是段内返回,则其操作为:(SP)IP 语句格式2:RET n;功能:用来废除栈顶n/2个无用的字参数。若是段间返回,操作为:(SP)IP(SP)CS(SP)+n SP 若是段内返回,操作为:(SP)IP(SP)+n SP,63,2现场的保护与恢复,例如:若子程序PROG中改变了寄存器AX,BX,CX,DX的值,则可采用如下方法保护和恢复现场。PROGPROCPUSHAX;保护现场PUSHBX PUSHCXPUSHDX,64,POPDX;恢复现场POP
31、CXPOPBXPOPAXRET;返回断点处PROCENDP,65,3主程序与子程序参数传递方式,常用的参数传递方式:(1)寄存器法:参数存放在约好的寄存器中,信息传递快、编程教方便、节省内存空间,但寄存器个数有限;(2)约定单元法:参数存放在约好的存储单元中,存放在独立的存储单元,编程时不易出错,但要占用一定的存储单元;(3)堆栈法:参数存放在公共的堆栈区,不占用寄存器、也不需开辟存储单元,处理完后堆栈恢复原状,仍可供其它程序使用,但参数和子程序的返回地址混杂在一起易出错。,66,【例4.14】编写将n个8位无符号二进制数排成递增序列的子程序。(P127 例1)子程序名:SORT入口参数:BX
32、存放待排序数组存储区首址 CX存放待排序数组元素的个数出口参数:已排成递增序列的n个无符号数仍放在由BX指示首址的字节存储区中所用寄存器:AX 用来存放Xi SI 用来存放i的值,初值为1,每外循环一次后增1,范围:1-(DX)DI 用来存放j的值,初值为i+1,每内循环一次后增1,范围:(i+1)-(CX)DX用来存放n-1,即(CX)-1,4.5.4 子程序应用举例,67,SORT PROC PUSH AX PUSH DX PUSH SI PUSH DI MOV DX,CX DEC DX MOV SI,1 LOPI:MOV DI,SI INC DI MOV AL,BX+SI-1,LOPJ:
33、CMP AL,BX+DI-1 JBE NEXT XCHG BX+DI-1,AL MOV BX+SI-1,ALNEXT:INC DI CMP DI,CX JBE LOPJ INC SI CMP SI,DX JBE LOPI,68,POP DIPOP SIPOP DXPOP AX RETSORT ENDP,思考:考虑调用该子程序的主程序的实现,及调用它的主程序和排序子程序之间是如何传递参数的?写出一个调用实例。,69,主程序:STACK SEGMENT STACK DB 100 DUP(0)STACK ENDSDATA SEGMENT BUF1 DB 30H,10H,40H,20H,50H,70H
34、,60H,90H,80H,0FFH N1=$-BUF1 BUF2 DB 22H,11H,33H,55H,44H,77H,66H,99H,88H,0AAH,0EEH,0 N2=$-BUF2DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK,70,BEGIN:MOV AX,DATA MOV DS,AX LEA BX,BUF1 MOV CX,N1 CALL SORT LEA BX,BUF2 MOV CX,N2 CALL SORT MOV AH,4CH INT 21H SORT PROC.SORT ENDPCODE ENDS END BEGIN,
35、71,【例4.14】将一个给定的二进制数按位转换成相应的ASCII码字符串,送到指定的存储单元并显示。如二进制数10010011转换成字符串为10010011。要求将转换过程写成子程序,且子程序应具有较好的通用性,而必须能实现对8 位和16位二进制数的转换。入口参数:DX=存放待转换的二进制数 CX=存放待转换数的位数(8位或16位)DI=存放ASCII码首地址出口参数:转换后的字符串存放在以DI作指针的字节存贮区中寄存器使用:AL:暂存某位二进制数对应的字符ASCII,72,程序如下:DATASEGMENT NUM8 DB 93H NUM16 DW 0ABCDH ASCBUF DB20DUP
36、(0)DATAENDSSTACK SEGMENT STACK DB 200 DUP(0)STACK ENDS,73,CODESEGMENTASSUME DS:DATA,CS:CODE,SS:STACKSTART:MOVAX,DATAMOVDS,AXMOVDX,0MOVDL,NUM8;转换二进制数送DXMOVCX,8;置位数8LEADI,ASCBUF;字符串首址DICALLBTASC;调用子程序BTASCMOVDI,BYTE PTR 0DHMOVDI+1,BYTE PTR 0AH,74,MOV DI+2,BYTE PTR$LEA DX,ASCBUFMOV AH,9INT 21HMOV DX,NU
37、M16MOV CX,16;置位数16 LEA DI,ASCBUFCALL BTASC MOV DI,BYTE PTR 0DHMOV DI+1,BYTE PTR 0AHMOV DI+2,BYTE PTR$LEA DX,ASCBUF MOV AH,9 INT 21H,75,BTASC PROC PUSH AX;保存AX CMP CX,8;比较8位数 JNEL1;直接转换16位数 MOVDH,DL;8位数转换送DHL1:ROLDX,1;DX最高位移入CF MOV AL,0 RCLAL,1;CF移入AL最低位 ADDAL,30H MOVDI,AL INCDI LOOPL1 POPAX,RETBTASC
38、 ENDPCODE ENDSEND START,返回本节,76,4.5.5 子程序的嵌套与递归调用,子程序不但可以被主程序调用,而且也可以被其他子程序调用。我们把一个子程序调用另一个子程序称为子程序的嵌套调用。,【例4.15】子程序嵌套的例子。,子程序名:HTOA功能:将一位16进制数转换为对应的ASCII码入口参数:待转换的数据在AL寄存器的低4位中出口参数:转换后的ASCII码在AL寄存器中,77,HOTA PROC AND AL,0FH CMP AL,10 JB NEXT ADD AL,7NEXT:ADD AL,30H RETHTOA ENDP,子程序HOTA:,78,现要求编制将AL中
39、的两位16进制数转换为对应的ASCII码子程序。,子程序名:BHTOA功能:将两位16进制数转换为对应的ASCII码入口条件:两位16进制数在AL中出口条件:高位16进制数对应的ASCII码在AH中,低位16进制数对应的ASCII码在AL中。使用寄存器:CX:CH复制AL的两位16进制数,CL存放移位次数,79,BHTOA PROC FAR PUSH CX MOV CH,AL MOV CL,4 SHR AL,CL CALL HTOA MOV AH,AL MOV AL,CH CALL HTOA POP CX RETBHTOA ENDP,返回本节,80,4.6 程序设计中的注意事项,1、依操作数个数的多少,值的大小,正确地分配数据存储区;2、选择合适的指令和寻址方式;A、要注意字节操作与字操作的区别;B、要选择合适的寻址方式,注意各种寻址方式之间的区别;C、要选用效率高的指令;D、不要插入不必要的语句;E、目的操作数不允许立即方式;F、两个存储器操作数不能出现在同一条指令之中;G、当立即数与存储器操作数进行运算时,一定要指出其长度;H、两个操作数的类型要匹配3、合理安排源程序的格式,返回本章首页,