




已阅读5页,还剩21页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1,第6章子程序设计,2,子程序又称为过程,是完成特定功能的程序段。本身不能被单独执行,必须通过调用的程序来执行才有意义。子程序结构是模块化程序设计的基础。一、过程定义伪指令格式:过程名PROCATTRIBUTERET过程名ENDP,过程入口的符号地址,NEAR/FAR,3,用户对过程属性的确定原则:(1)若调用程序和过程在同一个代码段中,则使用NEAR属性;(2)若调用程序和过程不在同一个代码段中,则使用FAR属性。二、子程序的调用和返回为方便用户的工作,80 x86的汇编程序用PROC伪操作的类型属性来确定CALL和RET指令的属性,即CALL和RET的属性由汇编程序确定,用户只需正确选择PROC的属性就可以了。子程序的调用采用指令CALL,其格式为:CALL过程名段内调用,4,CSEGSEGMENTMAINPROCFARCALLSUBTRETMAINENDPSUBTPROCNEARRETSUBTENDPCSEGENDS,段间调用SEGXSEGMENTSUBTPROCFARRETSUBTENDPCALLSUBT;第一次调用SEGXENDSSEGYSEGMENTCALLSUBT;第二次调用SEGYENDS,CALLfarptrSUBT(8086),5,(3)子程序的返回由RET指令实现过程的返回功能,由于CALL时,已使返回地址如栈,所以RET时应使返回地址出栈。因此,在执行RET前,SP应指向进入子程序时的返回地址,这样,才能使返回地址出栈,正确返回到主程序。,6,三、保存与恢复寄存器(现场保护与恢复)通常主程序和过程的设计是分开的,因而他们所使用的寄存器往往会发生冲突。为解决这一冲突,一般地,应该在子程序入口处将子程序中用到的寄存器内容压入堆栈保存,而在返回到调用程序之前再恢复这些寄存器。如:SUB1PROCNEARPUSHAX;进入后,压栈保护现场PUSHBX;处理部分POPBX;反序弹出,恢复现场POPAXRETSUB1ENDP但是,如果是用来向主程序回送结果的寄存器,则不应该保存其内容,否则会因为保存和恢复寄存器而破坏了应该向主程序传送的信息。,7,四、主、子程序间的参数传递方法主程序子程序子程序主程序,原始数据、地址,处理结果,参数传递,入口参数:主程序调用子程序时,必须先将子程序所需要的初始数据设置好,这些初始数据称为过程的入口参数。出口参数:子程序执行完毕返回主程序时也必须将子程序运行所得的结果送给主程序,这些回送的结果称为过程的出口参数。参数传递:过程入口参数的送入和出口参数的送出称为主程序和过程间的参数传递,也称过程通信。过程通信通常有四种方法:,8,1、通过寄存器传递参数2、通过变量传递参数3、通过地址表传递参数4、通过堆栈传递参数,1、通过寄存器传送参数最常用,但参数多时不宜使用。(1)主、子程序之间通过寄存器传递参数(2)子程序之间通过寄存器传递参数,9,例6.1:从键盘输入一个十进制数并将其以十六进制形式在屏幕上显示出来。十进制二进制数十六进制数decibin子程序binihex子程序功能:从键盘取得十进制数把BX中的二进制数转换成十六进制数转换,结果放BX并显示入口参数:键盘取得的十进要转换的二进制数在BX中制数放AL出口参数:转换结果放入BX转换结果放入AL(以备显示),BX在子程序之间传递参数,10,键盘输入的十进制数二进制数的转换算法:从最高位起,每个数位先将ASCII字符转换为数字,然后乘以该位的权,累加后就成为所要求的二进制数。例:从键盘输入数12345的计算步骤为:步骤成绩5X1=54X10=403X100=3002X1000=20001X10000=10000求和=12345,11,键盘输入的十进制数二进制数的转换算法步骤:(1)(bx)=0;(2)十进制数中的高位ASCII码转换为二进制数,并放于ax中;(3)(bx)(bx)x10+(ax);(4)重复(2)、(3)步,直到各位十进制数都转换为止,结果放bx中。,12,开始,调用DECIBIN,调用CRLF,调用BINIHEX,调用CRLF,结束,程序结构:,13,主程序:decihexsegmentmainprocfarassumecs:decihexstart:pushdssubax,axpushaxcalldecibin;keyboardtobinarycallcrlf;printcrandlfcallbinihex;binarytoscreencallcrlf;printcrandlfjmpstartret;在补充教材中补上mainendp,14,decibinprocnearmovbx,0;clearBXfornumbernewchar:movah,1int21hsubal,30h;ASCIItobinaryjlexit;jumpif9?jgexit;yes,notdecdigitcbw;byteinALtowordinAXpushax;saveaxmovax,bxmovcx,10;put10ddecincxmulcx;numbertimes10dmovbx,ax;(bx)*10to(bx)popaxaddbx,ax;adddigittonumberjmpnewchar;getnextdigitexit:retdecibinendp,;getdigitfromkeyboard,andconverttobinary,resultisleftinBX,15,;PROCEDURETOCONVERTBINARYINBXTOHEXONCONSOLESCREENbinihexprocnearmovch,4;countoflooprotate:movcl,4;setcountto4bitsrolbx,cl;leftdigittorightmoval,bl;movetoALandal,0fh;maskoffleftdigitaddal,30h;converthextoASCIIcmpal,3ah;jlprint;jumpifdigit=0to9addal,7h;digitisAtoFprint:movdl,al;putASCIIcharinDLmovah,2;Displayoutputfunctionint21hdecch;done4digits?jnzrotate;notyetretbinihexendp,16,;PROCEDURETOPRINTCARRIAGERETURNANDLINEFEEDcrlfprocnearmovdl,0dh;carriagereturnmovah,2;displayfunctionint21h;callDOSmovdl,0ah;linefeedmovah,2int21hretcrlfendp;-decihexends;endofcodesegmentendstart;endofprogram,17,2、通过变量传递参数如果过程和调用程序在同一程序模块(同一代码段)中,则过程可直接访问模块中的变量。例6.2主程序main和过程proadd在同一源文件中,要求用过程proadd累加数组中的所有元素,并把和送到指定的存储单元中。(不考虑溢出的可能性)datasegment;definedatasegmentarraydw1111h,2222h,3333hcountdw($-array)/2;3dsumdw?dataends,18,codesegmentmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxmovax,data;initializedssegmentmovds,axcallproaddretmainendp;endmainpartofprog.,19,proaddprocnear;definesubprocedurepushax;saveregisterspushcxpushsileasi,array;过程直接访问模块中的变量movcx,countxorax,ax;clearaxnext:addax,si;resultofaddingtoaxaddsi,2;pointtonextelementloopnextmovsum,axpopsipopcxpopaxretproaddendpcodeendsendstart,20,3、通过堆栈传送参数地址方法:在主程序里把参数地址保存到堆栈中,在子程序里从堆栈中取出参数以达到传送参数的目的。注意:为了在返回主程序后,堆栈能恢复原始状态不变,子程序结束时应使用带常数的返回指令retn。例6.3主程序main和过程proadd不在同一代码段中,要求用过程proadd累加数组中的所有元素,并把和送到指定的存储单元中。采用通过堆栈传送参数地址的方法编写程序。(不考虑溢出的可能性)datasegment;definedatasegmentarraydw1,2,3,4,5,6countdw($-array)/2sumdw?dataends,21,code1segmentmainprocfarassumecs:code1,ds:datastart:pushdssubax,axpushaxmovax,datamovds,axmovbx,offsetarraypushbxmovbx,offsetcountpushbxmovbx,offsetsumpushbxcallfarptrproaddretmainendpcode1ends,;initializeDS;pushaddressofarray;ontostack;pushaddressofcount;ontostack;pushaddressofsum;ontostack;endmainpartofprog;code1ends,22,code2segmentassumecs:code2proaddprocfar;子程序定义开始pushbp;栈框架指针movbp,sppushaxpushcxpushsipushdimovsi,bp+0ah;标准的读栈内参数的方法movdi,bp+8movcx,di;putcountinCXmovdi,bp+6xorax,ax;累加器清0,(sp),(ds),0000h,ary的偏移地址,count的偏移地址,sum的偏移地址,(cs),(ip),(sp),(bp),(ax),(cx),(si),(bp),(di),(sp),(bp)+0ah,(bp)+8h,返回地址,23,next:addax,si;计算和addsi,2;指向下一个元素loopnextmovdi,ax;返回结果到sum单元popdi;恢复寄存器popsipopcxpopaxpopbpret6;调整堆栈并返回调用程序proaddendpcode2endsendstart;结束汇编,(sp),(ds),0000h,ary的偏移地址,sum的偏移地址,(cs),(ip),(sp),(bp),(ax),(cx),(si),(bp),(di),(sp),count的偏移地址,执行ret6后(sp),返回地址,24,五、子程序的嵌套与递归调用一个子程序调用另一个子程序叫子程序嵌套,如下图所示:,CALLproc1,CALLproc2,CALL,RET,R
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年医学影像学CT检查典型病例分析答案及解析
- 工业园区供水工程商业计划书
- 2025年现代医学生物化学实验操作技能评估答案及解析
- 外周静脉留置针的护理
- 飞天凌空教材帮课件
- 2025年老年医学常见疾病诊治模拟试题答案及解析
- 2025年医学伦理学常见问题解决方法及道德决策考核试卷答案及解析
- 煤矿工人考试试题及答案
- 2025年口腔科种植手术操作规范性评定答案及解析
- 风险分级管控培训知识点课件
- 肠道准备课件
- 精神运动康复
- 660MW机组引风机变频改造:经济双维度剖析
- 2025年陕西省中考数学试题卷(含答案详解)
- 2025年注册计量师考试计量器具管理与维护试卷
- DGTJ08-2062-2017 住宅工程套内质量验收规范
- 景区信息安全管理办法
- 国内公司外汇管理办法
- 高中数学教师学情分析现状的调查研究
- 2025中国煤炭地质总局招聘应届生【338人】笔试参考题库附带答案详解
- 起重作业安全知识考核试题(含答案)
评论
0/150
提交评论