汇编语言最后1次

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

第4章4.4子程序设计把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率子程序设计要利用过程定义伪指令参数传递是子程序设计的重点和难点子程序可以嵌套;一定条件下,还可以递归和重入4.4.1过程定义伪指令过程名proc[near|far]...过程名endp过程名(子程序名)为符合语法的标识符NEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用对简化段定义格式,在微型、小型和紧凑存储模式下,过程的缺省属性为near;在中型、大型和巨型存储模式下,过程的缺省属性为far对完整段定义格式,过程的缺省属性为near用户可以在过程定义时用near或far改变缺省属性第4章子程序的常见格式subnameproc;具有缺省属性的subname过程pushax;保护寄存器:顺序压入堆栈pushbx;ax/bx/cx仅是示例pushcx…;过程体popcx;恢复寄存器:逆序弹出堆栈popbxpopaxret;过程返回subnameendp;过程结束;子程序功能:实现光标回车换行dpcrlfproc;过程开始pushax;保护寄存器AX和DXpushdxmovdl,0dh;显示回车movah,2int21hmovdl,0ah;显示换行movah,2int21hpopdx;恢复寄存器DX和AXpopaxret;子程序返回dpcrlfendp;过程结束例题无参数传递的子程序ALdispproc;实现al内容的显示pushax;过程中使用了AX、CX和DXpushcxpushdxpushax;暂存axmovdl,al;转换al的高4位movcl,4shrdl,clordl,30h;al高4位变成3cmpdl,39hjbealdisp1adddl,7;是0Ah~0Fh,还要加上7aldisp1:movah,2;显示int21h例4.15子程序-1/3popdx;恢复原ax值到dxanddl,0fh;转换al的低4位ordl,30hcmpdl,39hjbealdisp2adddl,7aldisp2:movah,2;显示int21hpopdxpopcxpopaxret;过程返回ALdispendp例4.10子程序-2/3...;主程序,同例4.8源程序movbx,offsetarray;调用程序段开始movcx,countdisplp:moval,[bx]callALdisp;调用显示过程movdl,',';显示一个逗号,分隔数据movah,2int21hincbxloopdisplp;调用程序段结束.exit0...;过程定义end例4.10主程序-3/3HTOASCproc;将AL低4位表达的一位16进制数转换为ASCII码andal,0fhcmpal,9jbehtoasc1addal,37h;是0AH~0FH,加37Hret;子程序返回htoasc1:addal,30h;是0~9,加30Hret;子程序返回HTOASCendp例题具有多个出口的子程序第4章4.4.2子程序的参数传递入口参数(输入参数):主程序提供给子程序出口参数(输出参数):子程序返回给主程序参数的形式:①数据本身(传值)②数据的地址(传址)传递的方法:①寄存器②变量③堆栈第4章例4.16求校验和子程序计算数组元素的“校验和”校验和是指不记进位的累加入口参数:数组的逻辑地址(传址)元素个数(传值)出口参数:求和结果(传值)把参数存于约定的寄存器中,可以传值,也可以传址。子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护)子程序对带有入口参数的寄存器可以保护,也可以不保护;但最好一致例4.16a入口参数:CX=元素个数,DS:BX=数组的段地址:偏移地址出口参数:AL=校验和用寄存器传递参数.startup;设置入口参数(含有DS←数组的段地址)movbx,offsetarray;BX←数组的偏移地址movcx,count;CX←数组的元素个数callchecksuma;调用求和过程movresult,al;处理出口参数.exit0例4.16a主程序checksumaprocxoral,al;累加器清0suma:addal,[bx];求和incbx;指向下一个字节loopsumaretchecksumaendpend例4.16a子程序主程序和子程序直接采用同一个变量名共享同一个变量,实现参数的传递不同模块间共享时,需要声明例4.16b入口参数:count=元素个数,array=数组名(段地址:偏移地址)出口参数:result=校验和用变量传递参数;主程序callchecksumb;子程序checksumbprocpushaxpushbxpushcxxoral,al;累加器清0movbx,offsetarray;BX←数组的偏移地址movcx,count;CX←数组的元素个数例4.16b-1/2sumb:addal,[bx];求和incbxloopsumbmovresult,al;保存校验和popcxpopbxpopaxretchecksumbendpend例4.16b-2/2主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们例4.16c入口参数:顺序压入偏移地址和元素个数出口参数:AL=校验和用堆栈传递参数.startupmovax,offsetarraypushaxmovax,countpushaxcallchecksumcaddsp,4movresult,al.exit0例4.16c主程序图示要注意堆栈的分配情况,保证参数存取正确、子程序正确返回,并保持堆栈平衡checksumcprocpushbpmovbp,sp;利用BP间接寻址存取参数pushbxpushcxmovbx,[bp+6];SS:[BP+6]指向偏移地址movcx,[bp+4];SS:[BP+4]指向元素个数xoral,alsumc:addal,[bx]incbxloopsumcpopcxpopbxpopbpretchecksumcendp例4.16c子程序图示第4章子程序的嵌套子程序内包含有子程序的调用就是子程序嵌套没有什么特殊要求ALdispprocpushaxpushcx;实现al内容的显示pushax;暂存axmovcl,4shral,cl;转换al的高4位callhtoasc;子程序调用(嵌套)popax;转换al的低4位callhtoasc;子程序调用(嵌套)popcxpopaxretALdispendp例4.15嵌套子程序-1/3;将AL低4位表达的一位16进制数转换为ASCII码HTOASCprocpushaxpushbxpushdxmovbx,offsetASCII;BX指向ASCII码表andal,0fh;取得一位16进制数xlatASCII;换码:AL←CS:[BX+AL],注意数据在代码段CS例4.15嵌套子程序-2/3movdl,al;显示movah,2int21hpopdxpopbxpopaxret;子程序返回;子程序的数据区ASCIIdb30h,31h,32h,33h,34h,35h,36h,37hdb38h,39h,41h,42h,43h,44h,45h,46hHTOASCendp例4.15嵌套子程序-3/3第4章子程序的递归当子程序直接或间接地嵌套调用自身时称为递归调用,含有递归调用的子程序称为递归子程序递归子程序必须采用寄存器或堆栈传递参数,递归深度受堆栈空间的限制例4.17:求阶乘010)!1(!NNNNN.modelsmall.stack256.dataNdw3resultdw?.code.startupmovbx,Npushbx;入口参数:Ncallfact;调用递归子程序popresult;出口参数:N!.exit0例4.17主程序-1/3图示;计算N!的近过程;入口参数:压入N;出口参数:弹出N!factprocpushaxpushbpmovbp,spmovax,[bp+6];取入口参数Ncmpax,0jnefact1;N>0,N!=N×(N-1)!incax;N=0,N!=1jmpfact2例4.17递归子程序-2/3图示fact1:decax;N-1pushaxcallfact;调用递归子程序求(N-1)!popaxmulwordptr[bp+6];求N×(N-1)!fact2:mov[bp+6],ax;存入出口参数N!popbppopaxretfactendpend例4.17递归子程序-3/3图示第4章子程序的重入子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。在子程序中,注意利用寄存器和堆栈传递参数和存放临时数据,而不要使用固定的存储单元(变量),就能够实现重入。子程序的重入不同于子程序的递归。重入是被动地进入,而递归是主动地进入;重入的调用间往往没有关系,而递归的调用间却是密切相关的。递归子程序也是可重入子程序。第4章例题4.18:从键盘输入有符号十进制数子程序从键盘输入一个有符号十进制数;子程序还包含将ASCII码转换为二进制数的过程输入时,负数用“-”引导,正数直接输入或用“+”引导子程序用寄存器传递出口参数,主程序调用该子程序输入10个数据转换算法.datacount=10arraydwcountdup(0);预留数据存储空间.code.startupmovcx,countmovbx,offsetarrayagain:callread;调用子程序输入一个数据mov[bx],ax;将出口参数存放缓冲区incbxincbxcalldpcrlf;调用子程序,光标回车换行以便输入下一个数据loopagain.exit0例题4.18-1/5;输入有符号10进制数的通用子程序;出口参数:AX=补码表示的二进制数值;说明:负数用“-”引导,正数用“+”引导或直接输入;数据范围是+32767~-32768readprocpushbxpushcxpushdxxorbx,bx;BX保存结果xorcx,cx;CX为正负标志,0为正,1为负movah,1;输入一个字符int21h例题4.18-2/5cmpal,'+';是“+”,继续输入字符jzread1cmpal,'-';是“-”,设置-1标志jnzread2;非“+”和“-”,转read2movcx,-1read1:movah,1;继续输入字符int21hread2:cmpal,'0‘;不是0~9之间的字符,则输入数据结束jbread3cmpal,'9'jaread3例题4.18-3/5转换算法subal,30h;是0~9之间的字符,则转换为二进制数;利用移位指令,实现数值乘10:BX←BX×10shlbx,1movdx,bxshlbx,1shlbx,1addbx,dx;movah,0addbx,ax;已输入数值乘10后,与新输入数值相加jmpread1;继续输入字符例题4.18-4/5转换算法read3:cmpcx,0jzread4negbx;是负数,进行求补read4:movax,bx;设置出口参数popdxpopcxpopbxret;子程序返回readendp;使光标回车换行的子程序dpcrlfproc...;省略dpcrlfendpend例题4.18-5/5第4章例题4.19:显示有符号十进制数子程序在屏幕上显示一个有符号十进制数;子程序还包含将二进制数转换为ASCII码的过程显示时,负数用“-”引导,正数直接输出、没有前导字符子程序的入口参数用共享变量传递,主程序调用该子程序显示10个数据转换算法.datacount=10arraydw1234,-1234,0,1,-1,32767dw-32768,5678,-5678,9000wtempdw?;共

1 / 46
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功