子程序结构课件

上传人:hs****ma 文档编号:592361427 上传时间:2024-09-20 格式:PPT 页数:64 大小:1.34MB
返回 下载 相关 举报
子程序结构课件_第1页
第1页 / 共64页
子程序结构课件_第2页
第2页 / 共64页
子程序结构课件_第3页
第3页 / 共64页
子程序结构课件_第4页
第4页 / 共64页
子程序结构课件_第5页
第5页 / 共64页
点击查看更多>>
资源描述

《子程序结构课件》由会员分享,可在线阅读,更多相关《子程序结构课件(64页珍藏版)》请在金锄头文库上搜索。

1、1第六章子程序结构6.1子程序的设计方法6.2嵌套与递归子程序6.3子程序举例6.4DOS系统功能调用26.1子程序的设计方法一、子程序指令二、子程序的调用与返回三、现场的保护与恢复四、子程序参数的传递3一、子程序指令w子程序是完成特定功能的一段程序w当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行w当运行完子程序功能后,采用RET返回指令回到主程序继续执行4一、子程序指令调用指令wCALL指令分成4种类型(类似JMP)nCALLlabel;段内调用、直接寻址nCALLr16/m16;段内调用、间接寻址nCALLfarptrlabel;段间调用、直接寻址n

2、CALLfarptrmem;段间调用、间接寻址wCALL指令需要保存返回地址:n段内调用偏移地址IP入栈SPSP2,SS:SPIPn段间调用偏移地址IP和段地址CS入栈SPSP2,SS:SPCSSPSP2,SS:SPIP5一、子程序指令返回指令w根据段内和段间、有无参数,分成4种类型nRET;无参数段内返回nRETi16;有参数段内返回nRET;无参数段间返回nRETi16;有参数段间返回w需要弹出CALL指令压入堆栈的返回地址n段内返回偏移地址IP出栈IPSS:SP,SPSP2n段间返回偏移地址IP和段地址CS出栈IPSS:SP,SPSP2CSSS:SP,SPSP26一、子程序指令返回指令R

3、ET的参数RETi16;有参数返回wRET指令可以带有一个立即数i16,则堆栈指针SP将增加,即SPSP+i16w这个特点使得程序可以方便地废除若干执行CALL指令以前入栈的参数7二、子程序的调用与返回CALLlabel主程序RET子程序回到CALL指令后的指令处返回地址8二、子程序的调用与返回书写形式(同一代码段内)9二、子程序的调用与返回书写形式(不同代码段)10三、现场的保护与恢复w现场:主程序转向子程序之前,其所使用的一些资源的状态(如标志位、R/M等)w子程序与主程序分别编制,通常会导致使用的资源发生冲突而影响主程序在调用子程序之后的正确执行w方法:利用堆栈n在主程序中进行n在子程序

4、中进行11三、现场的保护与恢复在主程序中进行PUSHBXPUSHAXCALLSUB1POPAXPOPBX注意:进栈/出栈的顺序保护与恢复的对象:主程序用到的存有数据、中间结果且在CALL指令后还要用到的R/M12三、现场的保护与恢复在子程序中进行SUB1PROCPUSHBXPUSHAXPOPAXPOPBXRETSUB1ENDP注意:进栈/出栈的顺序保护与恢复的对象:子程序用到的R/M13四、子程序参数的传递w入口参数(输入参数):主程序提供给子程序w出口参数(输出参数):子程序返回给主程序w参数的形式:数据本身(传值)数据的地址(传址)w传递的方法:寄存器变量堆栈14例:将两个给定的二进制数转

5、换成为二进制数的ASCII码形式并加以显示w对两个数进行转换、显示的工作是相同的,没有必要重复编写,以子程序的形式来完成w显示子程序需被告知:被显示内容的起始位置被显示内容的长度被转换的数及其长度存放结果的起始位置w转换子程序需被告知:15例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示(6-1-1.asm)w方法一:用寄存器传递参数w显示子程序:DI:被显示内容的起始位置指针CX:被显示内容的长度BX:被转换的数CX:被转换数的长度DI:存放结果的起始位置指针w转换子程序:16;转换子程序BINASCPROCREP1:ROLBX,1MOVDL,BLANDDL,01HADD

6、DL,30H;屏蔽除最低位外的其他位MOVDI,DLINCDILOOPREP1RETBINASCENDPBLBHDLDI17;显示子程序DISPPROCREP2:MOVAH,2MOVDL,DIINT21HINCDILOOPREP2MOVDL,0AH;设置显示后的光标位置MOVAH,2INT21HMOVDL,0DHMOVAH,2INT21HRETDISPENDP18DSEGSEGMENTPARADATABIN1DB35HBIN2DW0AB48HASCBUFDB20HDUP(?)DSEGENDSCSEGSEGMENTPARACODEASSUMECS:CSEG,DS:DSEG,SS:SSEGMAIN

7、PROCFARMOVAX,DSEGMOVDS,AXMOVBH,BIN1MOVCX,8LEADI,ASCBUFPUSHDIPUSHCXCALLBINASCPOPCXPOPDIPUSHDICALLDISPPOPDIADDDI,10HMOVBX,BIN2MOVCX,16PUSHDIPUSHCXCALLBINASCPOPCXPOPDICALLDISPMOVAX,4C00HINT21H;转换子程序BINASCPROCREP1:ROLBX,1MOVDL,BLANDDL,01HADDDL,30H;屏蔽除最低位外的其他位MOVDI,DLINCDILOOPREP1RETBINASCENDP;显示子程序DISP

8、PROCREP2:MOVAH,2MOVDL,DIINT21HINCDILOOPREP2MOVDL,0AH;设置显示后的光标位置MOVAH,2INT21HMOVDL,0DHMOVAH,2INT21HRETDISPENDPMAINENDPCSEGENDSENDMAIN;setentrypoint19例:将两个给定的二进制数转换成为二进制数的ASCII码形式并加以显示(6-1-2.asm)w方法二:用堆栈传递参数20方法二之主程序段MOVAH,BIN1;要转换的数进栈PUSHAXLEADI,ASCBUF;地址指针PUSHDIMOVAX,8;长度PUSHAXCALLBINASC;调用转换子程序MOVA

9、X,BIN2PUSHAXADDDI,10HPUSHDIMOVAX,16PUSHAXCALLBINASC21;转换并显示子程序BINASCPROCPUSHDIPUSHAXPUSHBXPUSHCXPUSHDXPUSHBPMOVBP,SPMOVBX,BP+18MOVDI,BP+16MOVCX,BP+14REP1:ROLBX,1MOVDL,BLANDDL,01H;屏蔽除最低位外的其他位ADDDL,30HMOVDI,DLMOVAH,6INT21HINCDILOOPREP1MOVAH,6MOVDL,0AHINT21HMOVAH,6MOVDL,0DHINT21HPOPBPPOPDXPOPCXPOPBXPOP

10、AXPOPDIRET6BINASCENDP22BP=SPBX地址IP长度进入子程序时的SPAXDIBIN1CXDXBPBP+14BP+16BP+18方法二之堆栈236.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从最高位开始:

11、累加和*10+本位的权值w十六进制数显示的实现BHH4BHL4BLH4BLL44BHH4BHL4BLH4BLL4BHH4AL从最高位开始27;例6-3,十进制到十六进制数的转换SSEGSEGMENTPARASTACKSTACKDW100HDUP(0)SSEGENDSDSEGSEGMENTPARADATADSEGENDSCSEGSEGMENTPARACODEASSUMECS:CSEG,DS:DSEG,SS:SSEGMAINPROCFARMOVAX,DSEG;MAKENECCESSARYINITALIZALITIONMOVDS,AXREPEAT: CALLDECIBINCALLCRLFCALLBI

12、NIHEXCALLCRLFJMPREPEATMOVAH,0AHINT21HMOVAX,4C00H;RETURNDOSINT21HMAINENDP28;从键盘获得十进制数并将其转换成十六进制数置于BX中DECIBIN PROCMOVBX,0NEWCHAR:MOVAH,1INT21HSUBAL,30HJLEXIT;非十进制数则退出CMPAL,9JGEXITCBWXCHGAX,BX;将原有的数*10后加新输入的数MOVCX,10MULCXXCHGAX,BXADDBX,AXJMPNEWCHAREXIT:RETDECIBIN ENDP29;将BX中的十六进制数转换成相应的ASCII码显示在屏幕上BINI

13、HEX PROCMOVCH,4;共四位十六进制数ROTATE: MOVCL,4ROLBX,CLMOVAL,BL;从最高位开始,将其移位至BX,AL的低4位ANDAL,0FHADDAL,30HCMPAL,3AHJLPRINTITADDAL,7;如为A-F的处理PRINTIT: MOVDL,ALMOVAH,2INT21HDECCHJNZROTATERETBINIHEX ENDPCRLFPROCMOVDL,0AHMOVAH,2INT21HMOVDL,0DHMOVAH,2INT21HRETCRLFENDPCSEGENDSENDMAIN;SETENTRYPOINT30例6.8把以ASCII码形式表示的十

14、进制数转换成二进制数(6-8-2.asm,6-8-1.asm增强型编程)w程序限制:转换后的二进制数不超过16位w转换方法:123455*1=55*01H=5H4*10 =404*0AH=28H3*100=3003*64H=12CH2*1000=20002*3E8H=7D0H1*10000=100001*2710H=2710H求和=12345求和=3039H从最低位开始31增强功能的过程定义伪操作格式:PROCNAMEPROCATTRIBUTESFIELDUSESREGISTERLIST,PARAMETERFIELDPROCNAMEENDPATTRIBUTESFIELD:DISTANCELAN

15、GUAGETYPE VISIBILITYPROLOGUE32增强功能的过程定义伪操作33例6.8.MODELSMALL.STACK64.DATAASCVAL DB12345BINVALDW?.CODEMAINPROCFARMOVAX,DATAMOVDS,AXLEABX,ASCVALPUSHBXLEABX,BINVALPUSHBXCALLCONVASCBINMOVBX,BINVALCALLBINIHEXMOVAX,4C00HINT21HMAINENDP34CONVASCBINPROCPASCALUSESAXBXCXSIDI,PAR1:WORD,PAR2:WORDLOCALASCLEN:WORD,

16、MULFACT:WORDMOVBX,10MOVSI,PAR1MOVDI,PAR2SUBDI,SIMOVASCLEN,DIMOVCX,DIADDSI,CXDECSIMOVMULFACT,1MOVDI,PAR2MOVWORDPTRDI,0NEXT:MOVAL,SIANDAX,000FHMULMULFACTADDDI,AXMOVAX,MULFACTMULBXMOVMULFACT,AXDECSILOOPNEXTRETCONVASCBINENDP35BINIHEX PROCMOVCH,4ROTATE: MOVCL,4ROLBX,CLMOVAL,BLANDAL,0FHADDAL,30HCMPAL,3AHJ

17、LPRINTITADDAL,7PRINTIT: MOVDL,ALMOVAH,2INT21HDECCHJNZROTATERETBINIHEXENDPENDMAIN;SETENTRYPOINT3637例:6.9十六进制到十进制数的转换w把从键盘输入的0-FFFF的十六进制正数转换成十进制数并在屏幕上显示出来nHexibin:键盘输入十六进制数其数值在BX中ncrlf:回车换行nBinidec:十六进制到十进制转换并显示38例6.9DISPEQU2HKEY_INEQU1HDOSCALLEQU21HSSEGSEGMENTPARASTACKSTACKDW100HDUP(0)SSEGENDSCSEGSEG

18、MENTPARACODEASSUMECS:CSEG,SS:SSEGMAINPROCFARMOVCL,4CALLHEXIBIN;调用十六进制数输入子程序CALLCRLFCALLBINIDEC;调用十六进制到十进制转换子程序CALLCRLFJMPMAINMOVAX,4C00HINT21HMAINENDP39例6.9;十六进制输入并转换为十六进制数值子程序,十六进制数值在BX中HEXIBIN PROCMOVBX,0NEWCHAR: MOVAH,KEY_ININTDOSCALLSUBAL,30HJLEXIT;非十六进制数值输入则结束输入CMPAL,10JLADD_TOSUBAL,27HCMPAL,10

19、HJGEEXITADD_TO: SHLBX,CL;新输入的数值(在AL的低四位上)加入到BX的低四位中MOVAH,0ADDBX,AXJMPNEWCHAREXIT:RETHEXIBIN ENDP40例6.9;十六进制到十进制转换并显示子程序;被除数是BX,除数分别是10000,1000,100,10,1,;;商是十进制;数,余数作为下次的被除数BINIDEC PROCMOVCX,10000DCALLDEC_DIVMOVCX,1000DCALLDEC_DIVMOVCX,100DCALLDEC_DIVMOVCX,10DCALLDEC_DIVMOVCX,1CALLDEC_DIVRETBINIDEC E

20、NDPDEC_DIVPROCMOVAX,BXMOVDX,0DIVCXMOVBX,DXMOVDL,ALADDDL,30HMOVAH,DISPINTDOSCALLRETDEC_DIVENDP41例6.9CRLFPROCMOVDL,0AHMOVAH,DISPINTDOSCALLMOVDL,0DHMOVAH,DISPINTDOSCALLRETCRLFENDPCSEGENDSENDMAIN42例6.10一个简单的信息检索系统w数据区里有10个不同的信息,编号为0-9,每个信息包括30个字符。编制程序从键盘接收0-9之间的编号,然后在屏幕上显示相应编号的信息内容。w(6-10.asm,6-10.doc)4

21、3SSEGSEGMENTPARASTACKstackDW100HDUP(0)SSEGENDSDSEGSEGMENTPARADataTHIRTYDB?MESG0DBThisismessage0-MESG1DBThisismessage1-MESG2DBThisismessage2-MESG3DBThisismessage3-MESG4DBThisismessage4-MESG5DBThisismessage5-MESG6DBThisismessage6-MESG7DBThisismessage7-MESG8DBThisismessage8-MESG9DBThisismessage9-LENEQU

22、MESG1-MESG0ERRMSG DBerror!invilidparameter!DSEGENDS例例6.10:1/344CSEGSEGMENTPARACODEASSUMECS:CSEG,DS:DSEG,SS:SSEGMAINPROCFARMOVAX,DSEGMOVDS,AXMOVTHIRTY,LENBEGIN:MOVAH,1INT21HSUBAL,0JCERRORCMPAL,9JAERRORPUSHAXMOVDL,0AHCALLDISPCHARMOVDL,0DHCALLDISPCHARPOPAXMOVBX,OFFSETMESG0MULTHIRTYADDBX,AXCALLDISPJMPBE

23、GINERROR:MOVBX,OFFSETERRMSGCALLDISPMOVAX,4C00HINT21H例例6.10:2/345DISPPROCMOVCX,30DISP1:MOVDL,BXCALLDISPCHARINCBXLOOPDISP1MOVDL,0AHCALLDISPCHARMOVDL,0DHCALLDISPCHARRETDISPENDPDISPCHARPROCMOVAH,2INT21HRETDISPCHARENDPMAINENDPCSEGENDSENDMAIN;SETENTRYPOINT例例6.10:3/346例6.11人名排序程序。从键盘键入最多30个人名,当所有人名都进入后,按字母

24、上升的次序将人名排序,并在屏幕上显示已排序后的人名(6-11)47wb10read:输入子程序(所占空间固定,但要将多出部分清为空格)wD10stor:将本次输入存储到表中(DI中是在表中起始地址的指针,同时计存储到表中的名字的个数)wg10sort:排序(冒泡排序)nH10xch:交换表中相邻项的顺序wK10disp:显示已排序的名字表wQ10clr:清屏wQ20curs:设置光标位置48DSEGSEGMENTPARADATANAMEPARLABELBYTEMAXLENDB21NAMELENDB?NAMEFLDDB21DUP(?)CRLFDB13,10,$ENDADDRDW?MESG1DBN

25、AME?,$NAMECTRDB0NAMETABDB30DUP(20DUP()NAMESAVDB20DUP(?),13,10,$SWAPPEDDB0DSEGENDSCSEGSEGMENTPARACODEASSUMECS:CSEG,DS:DSEGMAINPROCFARMOVAX,DSEGMOVDS,AXMOVES,AX例例6.11:1/649CLDLEADI,NAMETAB;表首址作为目的串的首址CALLQ10CLRCALLQ20CURSA20LOOP:CALLB10READ;调输入子程序CMPNAMELEN,0JZA30CALLD10STOR;存储JMPA20LOOPA30:CALLQ10CLR

26、CALLQ20CURSCMPNAMECTR,1JBEA40CALLG10SORTA40:CMPNAMECTR,0JBEEXITCALLK10DISPEXIT:MOVAX,4C00HINT21HMAINENDP例例6.11:2/650;名字输入子程序B10READPROCMOVAH,9LEADX,MESG1INT21HMOVAH,0AHLEADX,NAMEPARINT21HMOVAH,9LEADX,CRLFINT21HMOVBH,0;缓存区的空余部分填空格MOVBL,NAMELENMOVCX,21SUBCX,BXB20:MOVNAMEFLDBX,20HINCBXLOOPB20RETB10READ

27、ENDP;名字存储子程序D10STORPROC;名字个数计数器加1INCNAMECTRCLDLEASI,NAMEFLDMOVCX,10REPMOVSWRETD10STORENDP例例6.11:3/651;排序子程序G10SORTPROCSUBDI,40MOVENDADDR,DIG20:MOVSWAPPED,0;交换标志清0LEASI,NAMETABG30:MOVCX,20MOVDI,SIADDDI,20MOVAX,DIMOVBX,SIREPECMPSBJBEG40CALLH10XCH;调用交换顺序子程序G40:MOVSI,AXCMPSI,ENDADDRJBEG30CMPSWAPPED,0JNZ

28、G20RETG10SORTENDP例例6.11:4/652;交换表的内容H10XCH PROCMOVCX,10LEADI,NAMESAVMOVSI,BXREPMOVSWMOVCX,10MOVDI,BXREPMOVSWMOVCX,10LEASI,NAMESAVREPMOVSWMOVSWAPPED,1RETH10XCH ENDP;显示已排序的名字表K10DISPPROCLEASI,NAMETABK20:LEADI,NAMESAVMOVCX,10REPMOVSWMOVAH,9LEADX,NAMESAVINT21HDECNAMECTRJNZK20RETK10DISPENDP例例6.11:5/653;清

29、屏子程序Q10CLR PROCMOVAX,0600HMOVBH,61HSUBCX,CXMOVDX,184FHINT10HRETQ10CLR ENDP;设置光标位置子程序Q20CURSPROCMOVAH,2SUBBH,BHSUBDX,DXINT10HRETQ20CURSENDPCSEGENDSENDMAIN;SETENTRYPOINT例例6.11:6/6546.4DOS系统功能调用裸机裸机汇编语言程序55系统功能调用w21H号中断是DOS提供给用户的用于调用系统功能的中断,它有近百个功能供用户选择使用,主要包括设备管理、目录管理和文件管理三个方面的功能wROM-BIOS也以中断服务程序的形式,向

30、程序员提供系统的基本输入输出程序w汇编语言程序设计需要采用系统的各种功能程序w充分利用操作系统提供的资源是程序设计的一个重要方面,需要掌握56功能调用的格式通常按照如下4个步骤进行:w在AH寄存器中设置系统功能调用号w在指定寄存器中设置入口参数w执行指令INT21H(或ROM-BIOS的中断向量号)实现中断服务程序的功能调用w根据出口参数分析功能调用执行情况57字符输出的功能调用wDOS功能调用INT21Hn功能号:AH02Hn入口参数:DL字符的ASCII码n功能:在显示器当前光标位置显示给定的字符,光标右移一个字符位置。如按Ctrl-Break或Ctrl-C则退出;在当前显示器光标位置显示

31、一个问号MOVAH,02H;设置功能号:AH02HMOVDL,?;提供入口参数:DL?INT21H;DOS功能调用:显示58字符串输出的功能调用wDOS功能调用INT21Hn功能号:AH09Hn入口参数:nDS:DX欲显示字符串在主存中的首地址n字符串应以$(24H)结束n功能:在显示器输出指定的字符串w可以输出回车(0DH)和换行(0AH)字符产生回车和换行的作用59字符串输出的功能调用显示字符串(例)STRDBHello,Everybody!,0DH,0AH,$;在数据段定义要显示的字符串.MOVAH,09H;设置功能号:AH09HMOVDX,OFFSETSTR;提供入口参数:DX字符串的

32、偏移地址INT21H;DOS功能调用:显示60字符输入的功能调用wDOS功能调用INT21Hn功能号:AH01Hn出口参数:AL字符的ASCII码n功能:获得按键的ASCII代码值w调用此功能时,若无键按下,则会一直等待,直到按键后才读取该键值61字符输入的功能调用判断按键(例)GETKEY:MOVAH,01H;功能号:AH01HINT21H;功能调用CMPAL,Y;处理出口参数ALJEYESKEY;是“Y”CMPAL,NJENOKEY;是“N”JNEGETKEY.YESKEY:.NOKEY:.62字符串输入的功能调用wDOS功能调用INT21Hn功能号:AH0AHn入口参数:DS:DX缓冲区

33、首地址w执行该功能调用时,用户按键,最后用回车确认w本调用可执行全部标准键盘编辑命令;用户按回车键结束输入,如按CtrlBreak或CtrlC则中止关键要定义好缓冲区63字符串输入的功能调用缓冲区的定义w第1字节事先填入最多欲接收的字符个数(包括回车字符,可以是1255)w第2字节将存放实际输入的字符个数(不包括回车符)w第3字节开始将存放输入的字符串w实际输入的字符数多于定义数时,多出的字符丢掉,且响铃w接收的字符串最后一个总是回车符64字符串输入的功能调用输入字符串(例);定义缓冲区BUFDB81;第1个字节填入可能输入的最大字符数DB0;存放实际输入的字符数DB81DUP(0);存放输入的字符串.MOVDX,SEGBUF;伪指令SEG取得BUFFER的段地址MOVDS,DX;设置数据段DSMOVDX,OFFSETBUFMOVAH,0AHINT21H

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学/培训

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号