《六章子程序结构教案.ppt》由会员分享,可在线阅读,更多相关《六章子程序结构教案.ppt(64页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1六章子程序结构 Still waters run deep.流静水深流静水深,人静心深人静心深 Where there is life,there is hope。有生命必有希望。有生命必有希望26.1 子程序的设计方法一、子程序指令二、子程序的调用与返回三、现场的保护与恢复四、子程序参数的传递3一、子程序指令w子程序是完成特定功能的一段程序w当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行w当运行完子程序功能后,采用RET返回指令回到主程序继续执行4一、子程序指令调用指令wCALL指令分成4种类型(类似JMP)nCALL label;段内调用、直接寻址
2、nCALL r16/m16;段内调用、间接寻址nCALL far ptr label;段间调用、直接寻址nCALL far ptr mem;段间调用、间接寻址wCALL指令需要保存返回地址:n段内调用偏移地址IP入栈 SPSP2,SS:SPIPn段间调用偏移地址IP和段地址CS入栈 SPSP2,SS:SP CS SPSP2,SS:SP IP5一、子程序指令返回指令w根据段内和段间、有无参数,分成4种类型nRET;无参数段内返回nRET i16;有参数段内返回nRET;无参数段间返回nRET i16;有参数段间返回w需要弹出CALL指令压入堆栈的返回地址n段内返回偏移地址IP出栈 IPSS:SP
3、,SPSP2n段间返回偏移地址IP和段地址CS出栈 IPSS:SP,SPSP2 CSSS:SP,SPSP26一、子程序指令返回指令RET的参数RET i16;有参数返回wRET指令可以带有一个立即数i16,则堆栈指针SP将增加,即SPSP+i16w这个特点使得程序可以方便地废除若干执行CALL指令以前入栈的参数7二、子程序的调用与返回CALL label主程序RET子程序回到CALL指令后的指令处返回地址8二、子程序的调用与返回书写形式(同一代码段内)9二、子程序的调用与返回书写形式(不同代码段)10三、现场的保护与恢复w现场:主程序转向子程序之前,其所使用的一些资源的状态(如标志位、R/M等
4、)w子程序与主程序分别编制,通常会导致使用的资源发生冲突而影响主程序在调用子程序之后的正确执行w方法:利用堆栈n在主程序中进行n在子程序中进行11三、现场的保护与恢复在主程序中进行PUSH BXPUSH AXCALL SUB1POP AXPOP BX注意:进栈/出栈的顺序保护与恢复的对象:主程序用到的存有数据、中间结果且在CALL指令后还要用到的R/M12三、现场的保护与恢复在子程序中进行SUB1 PROCPUSH BXPUSH AXPOP AXPOP BXRETSUB1 ENDP注意:进栈/出栈的顺序保护与恢复的对象:子程序用到的R/M13四、子程序参数的传递w入口参数(输入参数):主程序提
5、供给子程序w出口参数(输出参数):子程序返回给主程序w参数的形式:数据本身(传值)数据的地址(传址)w传递的方法:寄存器 变量 堆栈14例:将两个给定的二进制数转换成为二进制数的ASCII 码形式并加以显示w对两个数进行转换、显示的工作是相同的,没有必要重复编写,以子程序的形式来完成w显示子程序需被告知:被显示内容的起始位置被显示内容的长度被转换的数及其长度存放结果的起始位置w转换子程序需被告知:15例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示(6-1-1.asm)w方法一:用寄存器传递参数w显示子程序:DI:被显示内容的起始位置指针CX:被显示内容的长度BX:被转换的
6、数CX:被转换数的长度DI:存放结果的起始位置指针w转换子程序:16;转换子程序 BINASCPROC REP1:ROL BX,1MOV DL,BLAND DL,01HADD DL,30H;屏蔽除最低位外的其他位MOV DI,DLINC DILOOP REP1RET BINASCENDPBLBHDLDI17;显示子程序DISPPROCREP2:MOV AH,2MOV DL,DIINT 21HINC DILOOP REP2MOV DL,0AH;设置显示后的光标位置MOV AH,2INT 21HMOV DL,0DHMOV AH,2INT 21HRETDISP ENDP18DSEG SEGMENT
7、PARA DATABIN1DB 35HBIN2 DW 0AB48HASCBUFDB 20H DUP(?)DSEGENDSCSEG SEGMENT PARA CODEASSUME CS:CSEG,DS:DSEG,SS:SSEGMAIN PROC FARMOV AX,DSEGMOV DS,AXMOV BH,BIN1MOV CX,8LEA DI,ASCBUFPUSH DIPUSH CXCALL BINASCPOP CXPOP DIPUSH DICALL DISPPOP DIADD DI,10HMOV BX,BIN2MOV CX,16PUSH DIPUSH CXCALL BINASCPOP CXPOP
8、 DICALL DISP MOV AX,4C00HINT 21H;转换子程序BINASCPROCREP1:ROL BX,1MOV DL,BLAND DL,01HADD DL,30H;屏蔽除最低位外的其他位MOV DI,DLINC DILOOP REP1RETBINASCENDP;显示子程序DISP PROCREP2:MOV AH,2MOV DL,DIINT 21HINC DILOOP REP2MOV DL,0AH;设置显示后的光标位置MOV AH,2INT 21HMOV DL,0DHMOV AH,2INT 21HRETDISP ENDPMAIN ENDPCSEG ENDSEND MAIN;se
9、t entry point19例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示(6-1-2.asm)w方法二:用堆栈传递参数20方法二之主程序段MOV AH,BIN1;要转换的数进栈PUSH AXLEA DI,ASCBUF;地址指针PUSH DIMOV AX,8;长度PUSH AXCALL BINASC;调用转换子程序MOV AX,BIN2PUSH AXADD DI,10HPUSH DIMOV AX,16PUSH AXCALL BINASC21;转换并显示子程序BINASCPROCPUSH DIPUSH AXPUSH BXPUSH CXPUSH DXPUSH BPMOV B
10、P,SPMOV BX,BP+18MOV DI,BP+16MOV CX,BP+14REP1:ROL BX,1MOV DL,BLAND DL,01H;屏蔽除最低位外的其他位ADD DL,30HMOV DI,DLMOV AH,6INT 21HINC DILOOP REP1 MOV AH,6MOV DL,0AHINT 21HMOV AH,6MOV DL,0DHINT 21H POP BPPOP DXPOP CXPOP BXPOP AXPOP DI RET 6BINASC ENDP22BP=SPBX地址IP长度进入子程序时的SPAXDIBIN1CXDXBPBP+14BP+16BP+18方法二之堆栈236
11、.2 嵌套与递归子程序w嵌套:子程序调用其他子程序,嵌套层数取决于堆栈的大小32K(基本不受限制)w递归:子程序调用自己,该情况要合理设置出口参数,否则会造成程序死锁246.3 子程序举例25例 6.3 十进制到十六进制数的转换(从键盘取得一个十进制数,然后把该数以十六进制的形式在屏幕上显示出来)26例 6.3 十进制到十六进制数的转换(6-3-1.DOC)w转换方法:1234(0*10+1)*10)+2)*10+3)*10+4从最高位开始:累加和*10+本位的权值w十六进制数显示的实现BHH4BHL4BLH4BLL44BHH4BHL4BLH4BLL4BHH4AL从最高位开始27;例6-3,十
12、进制到十六进制数的转换SSEG SEGMENT PARA STACK STACKDW 100H DUP(0)SSEG ENDS DSEG SEGMENT PARA DATADSEG ENDSCSEG SEGMENT PARA CODEASSUME CS:CSEG,DS:DSEG,SS:SSEGMAIN PROC FARMOV AX,DSEG;MAKE NECCESSARY INITALIZALITIONMOV DS,AXREPEAT:CALL DECIBINCALL CRLFCALL BINIHEXCALL CRLFJMP REPEATMOV AH,0AHINT 21HMOV AX,4C00H
13、;RETURN DOSINT 21HMAIN ENDP28;从键盘获得十进制数并将其转换成十六进制数置于BX中DECIBIN PROCMOV BX,0NEWCHAR:MOV AH,1INT 21HSUB AL,30HJL EXIT;非十进制数则退出CMP AL,9JG EXITCBWXCHG AX,BX;将原有的数*10后加新输入的数MOV CX,10MUL CXXCHG AX,BXADD BX,AXJMP NEWCHAREXIT:RETDECIBIN ENDP29;将BX中的十六进制数转换成相应的ASCII码显示在屏幕上BINIHEX PROC MOV CH,4;共四位十六进制数ROTATE
14、:MOV CL,4ROL BX,CLMOV AL,BL;从最高位开始,将其移位至BX,AL的低4位AND AL,0FHADD AL,30HCMP AL,3AHJL PRINTITADD AL,7;如为A-F的处理PRINTIT:MOV DL,ALMOV AH,2INT 21HDEC CHJNZ ROTATERETBINIHEX ENDPCRLFPROCMOV DL,0AHMOV AH,2INT 21HMOV DL,0DHMOV AH,2INT 21HRETCRLFENDPCSEG ENDSEND MAIN;SET ENTRY POINT30例 6.8 把以ASCII码形式表示的十进制数转换成二
15、进制数(6-8-2.asm,6-8-1.asm增强型编程)w程序限制:转换后的二进制数不超过16位w转换方法:123455*1=5 5*01H=5H4*10 =404*0AH=28H3*100=3003*64H=12CH2*1000=20002*3E8H=7D0H1*10000=100001*2710H=2710H求和=12345求和=3039H从最低位开始31增强功能的过程定义伪操作格式:PROCNAMEPROC ATTRIBUTES FIELD USES REGISTER LIST,PARAMETER FIELDPROCNAMEENDPATTRIBUTES FIELD:DISTANCE L
16、ANGUAGE TYPE VISIBILITYPROLOGUE32增强功能的过程定义伪操作33例6.8.MODEL SMALL.STACK 64.DATAASCVAL DB 12345BINVALDW?.CODEMAIN PROC FARMOV AX,DATAMOV DS,AXLEA BX,ASCVALPUSH BXLEA BX,BINVALPUSH BXCALL CONVASCBIN MOV BX,BINVALCALL BINIHEX MOV AX,4C00HINT 21HMAIN ENDP34CONVASCBINPROC PASCAL USES AX BX CX SI DI,PAR1:WO
17、RD,PAR2:WORDLOCAL ASCLEN:WORD,MULFACT:WORDMOV BX,10MOV SI,PAR1MOV DI,PAR2SUB DI,SIMOV ASCLEN,DIMOV CX,DIADD SI,CXDEC SIMOV MULFACT,1MOV DI,PAR2MOV WORD PTR DI,0NEXT:MOV AL,SIAND AX,000FHMUL MULFACTADD DI,AXMOV AX,MULFACTMUL BXMOV MULFACT,AXDEC SILOOP NEXTRETCONVASCBINENDP35BINIHEX PROC MOV CH,4ROTAT
18、E:MOV CL,4ROL BX,CLMOV AL,BLAND AL,0FHADD AL,30HCMP AL,3AHJL PRINTITADD AL,7PRINTIT:MOV DL,ALMOV AH,2INT 21HDEC CHJNZ ROTATERETBINIHEX ENDPEND MAIN;SET ENTRY POINT3637例:6.9 十六进制到十进制数的转换 w把从键盘输入的0-FFFF的十六进制正数转换成十进制数并在屏幕上显示出来nHexibin:键盘输入十六进制数其数值在BX中ncrlf:回车换行nBinidec:十六进制到十进制转换并显示38例6.9DISPEQU 2HKEY_
19、INEQU 1HDOSCALL EQU 21HSSEG SEGMENT PARA STACK STACKDW 100H DUP(0)SSEG ENDS CSEG SEGMENT PARA CODEASSUME CS:CSEG,SS:SSEGMAINPROC FARMOV CL,4CALL HEXIBIN;调用十六进制数输入子程序CALL CRLF CALL BINIDEC;调用十六进制到十进制转换子程序CALL CRLFJMP MAINMOV AX,4C00HINT 21HMAIN ENDP39例6.9;十六进制输入并转换为十六进制数值子程序,十六进制数值在BX中HEXIBIN PROC MO
20、V BX,0 NEWCHAR:MOV AH,KEY_ININT DOSCALLSUB AL,30HJL EXIT;非十六进制数值输入则结束输入CMP AL,10JL ADD_TOSUB AL,27HCMP AL,10HJGE EXITADD_TO:SHL BX,CL;新输入的数值(在AL的低四位上)加入到BX的低四位中MOV AH,0ADD BX,AXJMP NEWCHAREXIT:RETHEXIBIN ENDP40例6.9;十六进制到十进制转换并显示子程序;被除数是BX,除数分别是10000,1000,100,10,1,;;商是十进制;数,余数作为下次的被除数BINIDEC PROCMOV
21、CX,10000DCALL DEC_DIVMOV CX,1000DCALL DEC_DIVMOV CX,100DCALL DEC_DIVMOV CX,10DCALL DEC_DIVMOV CX,1CALL DEC_DIVRETBINIDEC ENDPDEC_DIVPROCMOV AX,BXMOV DX,0DIV CXMOV BX,DXMOV DL,ALADD DL,30HMOV AH,DISPINT DOSCALLRETDEC_DIVENDP41例6.9CRLFPROCMOV DL,0AHMOV AH,DISPINT DOSCALLMOV DL,0DHMOV AH,DISPINT DOSCAL
22、LRETCRLFENDP CSEG ENDSEND MAIN42例6.10 一个简单的信息检索系统w数据区里有10个不同的信息,编号为0-9,每个信息包括30个字符。编制程序从键盘接收0-9之间的编号,然后在屏幕上显示相应编号的信息内容。w(6-10.asm,6-10.doc)43SSEG SEGMENT PARA STACK stackDW 100H DUP(0)SSEG ENDS DSEG SEGMENT PARA DataTHIRTYDB?MESG0DB This is message 0-MESG1DB This is message 1-MESG2DB This is message
23、 2-MESG3DB This is message 3-MESG4DB This is message 4-MESG5DB This is message 5-MESG6DB This is message 6-MESG7DB This is message 7-MESG8DB This is message 8-MESG9DB This is message 9-LENEQU MESG1-MESG0ERRMSG DB error!invilid parameter!DSEG ENDS例例6.10:1/344CSEG SEGMENT PARA CODEASSUME CS:CSEG,DS:DS
24、EG,SS:SSEGMAIN PROC FARMOV AX,DSEGMOV DS,AXMOV THIRTY,LENBEGIN:MOV AH,1INT 21HSUB AL,0JC ERRORCMP AL,9JA ERROR PUSH AXMOV DL,0AHCALL DISPCHARMOV DL,0DHCALL DISPCHARPOP AXMOV BX,OFFSET MESG0MUL THIRTYADD BX,AXCALL DISPJMP BEGIN ERROR:MOV BX,OFFSET ERRMSGCALL DISP MOV AX,4C00HINT 21H例例6.10:2/345DISPPR
25、OCMOV CX,30DISP1:MOV DL,BXCALL DISPCHARINC BXLOOP DISP1MOV DL,0AHCALL DISPCHARMOV DL,0DHCALL DISPCHARRETDISPENDP DISPCHARPROCMOV AH,2INT 21HRET DISPCHARENDP MAIN ENDPCSEGENDSEND MAIN;SET ENTRY POINT例例6.10:3/346例6.11 人名排序程序。从键盘键入最多30个人名,当所有人名都进入后,按字母上升的次序将人名排序,并在屏幕上显示已排序后的人名(6-11)47w b10read:输入子程序(所占
26、空间固定,但要将多出部分清为空格)wD10stor:将本次输入存储到表中(DI中是在表中起始地址的指针,同时计存储到表中的名字的个数)wg10sort:排序(冒泡排序)nH10 xch:交换表中相邻项的顺序 wK10disp:显示已排序的名字表 wQ10clr:清屏 wQ20curs:设置光标位置 48DSEG SEGMENT PARA DATA NAMEPARLABEL BYTE MAXLENDB 21 NAMELENDB?NAMEFLDDB 21 DUP(?)CRLFDB 13,10,$ENDADDRDW?MESG1DB NAME?,$NAMECTRDB 0 NAMETABDB 20 DU
27、P(20 DUP()NAMESAVDB 20 DUP(?),13,10,$SWAPPEDDB 0DSEG ENDSCSEG SEGMENT PARA CODEASSUME CS:CSEG,DS:DSEGMAIN PROC FARMOV AX,DSEGMOV DS,AXMOV ES,AX例例6.11:1/649CLDLEA DI,NAMETAB;表首址作为目的串的首址CALL Q10CLRCALL Q20CURS A20LOOP:CALL B10READ;调输入子程序CMP NAMELEN,0JZ A30CALL D10STOR;存储JMP A20LOOPA30:CALL Q10CLRCALL
28、Q20CURSCMP NAMECTR,1JBE A40CALL G10SORTA40:CMP NAMECTR,0JBE EXITCALL K10DISPEXIT:MOV AX,4C00HINT 21HMAIN ENDP例例6.11:2/650;名字输入子程序 B10READPROCMOV AH,9LEA DX,MESG1INT 21HMOV AH,0AHLEA DX,NAMEPARINT 21HMOV AH,9LEA DX,CRLFINT 21HMOV BH,0;缓存区的空余部分填空格MOV BL,NAMELENMOV CX,21SUB CX,BXB20:MOV NAMEFLDBX,20HIN
29、C BXLOOP B20RET B10READENDP ;名字存储子程序 D10STORPROC;名字个数计数器加1INC NAMECTRCLDLEA SI,NAMEFLDMOV CX,10REP MOVSWRET D10STORENDP例例6.11:3/651;排序子程序 G10SORTPROCSUB DI,40MOV ENDADDR,DIG20:MOV SWAPPED,0;交换标志清0LEA SI,NAMETABG30:MOV CX,20MOV DI,SIADD DI,20MOV AX,DIMOV BX,SIREPE CMPSBJBE G40CALL H10XCH;调用交换顺序子程序G40
30、:MOV SI,AXCMP SI,ENDADDRJBE G30CMP SWAPPED,0JNZ G20RET G10SORTENDP例例6.11:4/652;交换表的内容H10XCH PROCMOV CX,10LEA DI,NAMESAVMOV SI,BXREP MOVSWMOV CX,10MOV DI,BXREP MOVSW MOV CX,10LEA SI,NAMESAVREP MOVSW MOV SWAPPED,1RETH10XCH ENDP;显示已排序的名字表 K10DISPPROCLEA SI,NAMETABK20:LEA DI,NAMESAVMOV CX,10REP MOVSWMOV
31、 AH,9LEA DX,NAMESAVINT 21HDEC NAMECTRJNZ K20RET K10DISPENDP例例6.11:5/653;清屏子程序Q10CLR PROCMOV AX,0600HMOV BH,61HSUB CX,CXMOV DX,184FHINT 10HRETQ10CLR ENDP;设置光标位置子程序 Q20CURSPROCMOV AH,2SUB BH,BHSUB DX,DXINT 10HRET Q20CURSENDPCSEG ENDSEND MAIN;SET ENTRY POINT例例6.11:6/6546.4 DOS系统功能调用裸机裸机汇编语言程序55系统功能调用w2
32、1H号中断是DOS提供给用户的用于调用系统功能的中断,它有近百个功能供用户选择使用,主要包括设备管理、目录管理和文件管理三个方面的功能wROM-BIOS也以中断服务程序的形式,向程序员提供系统的基本输入输出程序w汇编语言程序设计需要采用系统的各种功能程序w充分利用操作系统提供的资源是程序设计的一个重要方面,需要掌握56功能调用的格式通常按照如下4个步骤进行:w在AH寄存器中设置系统功能调用号w在指定寄存器中设置入口参数w执行指令INT 21H(或ROM-BIOS的中断向量号)实现中断服务程序的功能调用w根据出口参数分析功能调用执行情况57字符输出的功能调用wDOS功能调用INT 21Hn功能号
33、:AH02Hn入口参数:DL字符的ASCII码n功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置。如按Ctrl-Break或Ctrl-C则退出;在当前显示器光标位置显示一个问号MOV AH,02H;设置功能号:AH02HMOV DL,?;提供入口参数:DL?INT 21H;DOS功能调用:显示58字符串输出的功能调用wDOS功能调用INT 21Hn功能号:AH09Hn入口参数:nDS:DX欲显示字符串在主存中的首地址n字符串应以$(24H)结束n功能:在显示器输出指定的字符串w可以输出回车(0DH)和换行(0AH)字符产生回车和换行的作用59字符串输出的功能调用显示字符串(例)S
34、TR DB Hello,Everybody!,0DH,0AH,$;在数据段定义要显示的字符串.MOV AH,09H ;设置功能号:AH09HMOV DX,OFFSET STR;提供入口参数:DX字符串的偏移地址INT 21H ;DOS功能调用:显示60字符输入的功能调用wDOS功能调用INT 21Hn功能号:AH01Hn出口参数:AL字符的ASCII码n功能:获得按键的ASCII代码值w调用此功能时,若无键按下,则会一直等待,直到按键后才读取该键值61字符输入的功能调用判断按键(例)GETKEY:MOV AH,01H;功能号:AH01HINT 21H;功能调用CMP AL,Y;处理出口参数AL
35、JE YESKEY;是“Y”CMP AL,NJE NOKEY;是“N”JNE GETKEY.YESKEY:.NOKEY:.62字符串输入的功能调用wDOS功能调用INT 21Hn功能号:AH0AHn入口参数:DS:DX缓冲区首地址w执行该功能调用时,用户按键,最后用回车确认w本调用可执行全部标准键盘编辑命令;用户按回车键结束输入,如按CtrlBreak或CtrlC则中止关键要定义好缓冲区63字符串输入的功能调用缓冲区的定义w第1字节事先填入最多欲接收的字符个数(包括回车字符,可以是1255)w第2字节将存放实际输入的字符个数(不包括回车符)w第3字节开始将存放输入的字符串w实际输入的字符数多于定义数时,多出的字符丢掉,且响铃w接收的字符串最后一个总是回车符64字符串输入的功能调用输入字符串(例);定义缓冲区BUFDB 81;第1个字节填入可能输入的最大字符数DB 0;存放实际输入的字符数DB 81 DUP(0);存放输入的字符串.MOV DX,SEG BUF;伪指令SEG取得BUFFER的段地址MOV DS,DX;设置数据段DSMOV DX,OFFSET BUFMOV AH,0AHINT 21H