1、四、子程序结构四、子程序结构 将反复进行的操作编成一个子程序,这样,只需编写一将反复进行的操作编成一个子程序,这样,只需编写一次,测试一次便可以多次重复使用。从而提高开发的效次,测试一次便可以多次重复使用。从而提高开发的效率。率。 实现模块化的重要手段。使程序便于开发、测试和维护。实现模块化的重要手段。使程序便于开发、测试和维护。主程序主程序CALL SUB1子程序子程序SUB1 PROC断点地址断点地址转向子程序转向子程序RET返回主程序返回主程序子程序的设计方法子程序的设计方法1.功能分析与说明功能分析与说明*子程序的名称,功能及性能子程序的名称,功能及性能*子程序中用到的寄存器和存储单元
2、子程序中用到的寄存器和存储单元*子程序的入口参数,出口参数子程序的入口参数,出口参数*子程序中调用其它子程序的名称子程序中调用其它子程序的名称主控主控数据处理数据处理输入输入输出输出;名称:;名称:BCD2BIN;功能:一个字节的;功能:一个字节的BCD码转换成码转换成二进制数二进制数;所用寄存器:;所用寄存器:CX;入口参数:;入口参数:AL中存两位中存两位BCD数数;出口参数:;出口参数:AL存二进制数存二进制数;调用其它子程序:无;调用其它子程序:无BCD2BIN PROC NEAR(FAR) PUSH CX MOV CH,AL AND CH,0FH MOV CL,4 SHR AL,CL
3、 ;/16 MOV CL,10 MUL CL ;*10 ADD AL,CH ;+低位低位 POP CX RETBCD2BIN ENDP例例5-7 一个子程序一个子程序2.参数传递技术参数传递技术入口参数与出口参数入口参数与出口参数参数传递方法参数传递方法1)利用寄存器传递参数利用寄存器传递参数2)利用存储器传递参数利用存储器传递参数3)利用堆栈传递参数利用堆栈传递参数1) 利用寄存器传递参数利用寄存器传递参数上例上例5-7DATA SEGMENT ARY1 DW 100 DUP(?)(?) SUM1 DW ? ARY2 DW 100 DUP(?)(?) SUM2 DW ?DATA ENDSST
4、ACK SEGMENT STACK SA DW 50 DUP(?)(?) TOP EQU LENGTH SASTACK ENDSCODE SEGMENT ASSUME CS: CODE,DS:DATA,SS:STACKMAIN PROC FAR例例5-8. 5-8. 数据段定义两个数组,编程实现数组段分别求和数据段定义两个数组,编程实现数组段分别求和(不计溢出)(不计溢出)。P182183P182183START: PUSH DS SUB AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV AX,STACK MOV SS,AX MOV SP,TOP TOP EQU
5、SIZE SA TOP LABEL WORD2) 利用存储器传递参数利用存储器传递参数 数据放在数据段中数据放在数据段中 LEA SI,ARY1;数组;数组1 1地址地址SISI MOV CX,LENGTH ARY1 CALL SUM;数组;数组1 1求和求和 LEA SI,ARY2;数组;数组2 2地址地址SISI MOV CX,LENGTH ARY2 CALL SUM ;数组;数组2 2求和求和 RETMAIN ENDPSUM PROC NEAR XOR AX,AX;AXAX清清0 0L1: ADD AX,WORD PTRSI INC SI INC SI LOOP L1 MOV WORD
6、PTR SI,AX RETSUM ENDPCODE ENDS END START2) 利用存储器传递参数利用存储器传递参数 数据放在数据段中数据放在数据段中 数据放在代码段中数据放在代码段中 获取参数的方法:获取参数的方法: 获得返回地址获得返回地址 根据返回地址实现参数传递根据返回地址实现参数传递 修改返回地址修改返回地址IPHIPLSPSP-1SP-2BPLBPHCALL SUBRDW BUFLDW BUFADW BUFBMOV AX, DXSUBR PROC PUSH BP MOV BP,SPMOV BX, BP+2 MOV CX, CS: BXMOV SI, CS:BX+2 MOV D
7、I, CS:BX+4 ADD BX,6 MOV BP+2,BX POP BP RETSUBRENDPMOV BX, SP+23)利用堆栈传递参数利用堆栈传递参数DATA SEGMENTBUFFER1 DW BUFA BUFFER2 DW BUFBBUFL DW NDATA ENDS主程序:主程序:LEA BX,BUFFER1PUSH BX PUSH BX+2PUSH BX+4CALL SUBRMOV AX, BXSP-2SP-1SPIPHBUFAHBUFALNLBUFBLNHBUFBHIPLSP-7SP-5SP-6SP-8SP-4SP-3BPLBPHSP-9SP-A子程序:子程序:SUBR:
8、PUSH BP MOV BP,SP MOV CX,BP+4 MOV DI, BP+6 MOV SI, BP+8 POP BP RET 6例例5-9.5-9.利用堆栈利用堆栈编程实现十进制数组求和,段间调用。编程实现十进制数组求和,段间调用。MDATA SEGMENT ARY1 DB 20 DUP(?)(?);数组数组1 1 SUM1 DW ? ARY2 DB 100 DUP(?)(?);数组数组2 2 SUM2 DW ?MDATA ENDSMSTACK SEGMENT STACK SB DW 100 DUP(?)(?) TOP LABEL WORDMSTACK ENDSMCODE SEGMEN
9、T ASSUME CS: MCODE,DS:MDATA,SS:MSTACKMAIN PROC FARSTART: PUSH DS SUB AX,AX PUSH AX MOV AX,MDATA MOV DS,AX MOV AX,MSTACK MOV SS,AX MOV SP,OFFSET TOP MOV AX,OFFSET ARY1 PUSH AX MOV AX,SIZE ARY1 PUSH AX CALL FAR PTR PADD MOV AX,OFFSET ARY2 PUSH AX MOV AX,SIZE ARY2 PUSH AX CALL FAR PTR PADD RETMAIN ENDP
10、MCODE ENDSPCODE SEGMENT ASSUME CS: PCODE,DS:MDATA,SS:MSTACKPADD PROC FAR PUSH BX PUSH CX PUSH BP MOV BP,SP PUSHFSPARY1SIZE1CSIPFBPCXBXSP-8SP-4SP-2SP-CSP-6SP-ASP-ESP-10 MOV CX,BP+10 MOV BX,BP+12 MOV AX,0NEXT: ADD AL,BX DAA MOV DL,AL MOV AL,0 ADC AL,AH DAA MOV AH,AL MOV AL,DL INC BX LOOP NEXT MOV BX,A
11、X POPF POP BP POP CX POP BX RET 4PADD ENDPPCODE ENDSEND STARTSPARY1SIZE1CSIPFBPCXBXSP-8SP-4SP-2SP-CSP-6SP-ASP-ESP-103. 现场保护和恢复现场保护和恢复1)1)一定要保护:子程序中使用的寄存器;在返回后主程序需继续一定要保护:子程序中使用的寄存器;在返回后主程序需继续使用的寄存器。使用的寄存器。2)2)一定不能保护:作为子程序的结果传送给主程序的寄存器。一定不能保护:作为子程序的结果传送给主程序的寄存器。3)3)可不必保护可不必保护( (随意随意) ):子程序中使用,返回主程序后不
12、再使用的:子程序中使用,返回主程序后不再使用的寄存器。寄存器。例例4. 子程序的嵌套与递归调用子程序的嵌套与递归调用嵌套嵌套子程序再调用其他子程序子程序再调用其他子程序递归递归子程序调用自身子程序调用自身嵌套的层数仅受堆栈空间的限制嵌套的层数仅受堆栈空间的限制注意寄存器的保护注意寄存器的保护例例5-9. 编制计算编制计算N!的程序!的程序 P186189 N!=1N=0 N!=N(N-1)!N0段寄存器初始化段寄存器初始化NAL调用调用FACT保存结果保存结果结束返回结束返回AL=0?开始开始AX(N)入栈入栈AL-1(N-1)调用调用FACTAX(N)出栈出栈N(N-1)!DX返回返回NYD
13、L=1返回返回例例5-10 将将16位位2进制数转换为进制数转换为4位压缩型位压缩型BCD码。码。P182DL+AL DLDX左移左移4位位余数余数AL,AH=0AX/10DL+AL DLDX左移左移4位位DL+AH DLDX AX恢复相关寄存器恢复相关寄存器返回返回开始开始CF=1AX=0返回返回YAX9999?保护相关保护相关寄存器寄存器(DX,AX)/1000商商DX,余数,余数AXDX左移左移4位位AX/100N输入参数:输入参数:AX=16位位2进制数。进制数。输出参数:输出参数:CF=0,则则AX=4位压缩位压缩BCD码。码。CF=1, 则要转换的数大于则要转换的数大于9999,A
14、X=0.使用寄存器:使用寄存器:CX:存放除数,:存放除数,DX:存放中间结果。存放中间结果。2)ASCII码转换为二进制码转换为二进制例例5-11将十进制数的将十进制数的ASCII字符串转换为有符号的二进制。字符串转换为有符号的二进制。P183(A010)+A1) 10 +A2) 10 +A3) 10)+An开始开始初始化:保护,初始化:保护,DXSICX6?检查符号位检查符号位?N+?NY置符号位置符号位BCX-1,SI+1YNDX 10 读下一字节读下一字节AL CF=1?YN合法?合法?YANDX +AX DX DABDX=0CNEXT:AYERR:NDCF=1?YANCX-1=0?C
15、YDX AX负数?负数?NY求补求补ACF=1,AX=0CX,DX出栈出栈返回返回ERR:EXIT: 例例5-125-12. .把二进制数码串中每一字节的两位十六进制数把二进制数码串中每一字节的两位十六进制数转换为转换为ASCIIASCII码。高位在高地址,低位在低地址。码。高位在高地址,低位在低地址。BUFFERSTRINGA42C533B4134433233354233主程序主程序16进制数首地址进制数首地址BXBXASCIIASCII码码首地址首地址SISI 长度长度CXCX取待转换数取待转换数 ALDLALDL分离出低分离出低4位位分离出高分离出高4位右移四位位右移四位调用调用CHANGE子程序子程序(CX)-1=0=0结结 束束AGAINN调用调用CHANGE子程序子程序Y(AL)10(AL)07HALAL(AL)30HALAL(AL)(SI)(SI)(SI)+1SI(SI)+1SIRETADD_0CHANGE子程序框图子程序框图YN