第4章 基本汇编语言程序设计-子程序设计.ppt
朱 泽 民 计算机科学与技术学院 139959390094.4 子程序设计子程序设计汇编语言程序设计NO!23模块化程序设计模块化程序设计n基本思想:q将一个复杂的功能分解成若干相对独立的子功能,并采用模块来实现。n优点:q便于大型程序的模块化组织q增强程序的结构性和可读性q便于分工合作,避免重复劳动n在汇编语言中,功能模块由子程序实现。41 子程序的定义子程序的定义n子程序:main()floatfirst,second;first=123.23;second=99.09;printf(“%f”,sum(first,second);/*函数调用函数调用*/floatsum(a,b)/*函数定义;功能是求两个浮点数的和函数定义;功能是求两个浮点数的和*/floata,b;returna+b;是指完成一定功能的程序段,相当于高级语言中的过程过程或函数函数。51 子程序的定义子程序的定义 1.1 定义子程序的一般格式 子程序名 PROCNEAR|FAR ;子程序体 RET 子程序名 ENDP61 子程序的定义子程序的定义1.1 定义子程序的一般格式 子程序名 PROCNEAR|FAR ;子程序体 RET 子程序名 ENDP“PROC”和“ENDP”分别为定义子程序开始和结束的关键字。它们必须成对出现。71 子程序的定义子程序的定义1.1 定义子程序的一般格式 子程序名 PROCNEAR|FAR ;子程序体 RET 子程序名 ENDP“子程序名子程序名”是子程序的标识符。注意前后二者要一致。81 子程序的定义子程序的定义1.1 定义子程序的一般格式 子程序名 PROCNEAR|FAR ;子程序体 RET 子程序名 ENDP“RET”为返回指令,是子程序的出口语句,相当于C语言中的Return语句。一个子程序至少需要一条RET指令。91 子程序的定义子程序的定义1.1 定义子程序的一般格式 子程序名 PROCNEAR|FAR ;子程序体 RET 子程序名 ENDP“”代表子程序体,是实现子程序功能的指令系列。101 子程序的定义子程序的定义1.1 定义子程序的一般格式 子程序名 PROCNEAR|FAR ;子程序体 RET 子程序名 ENDP“NEAR|FAR”表示子程序的类型属性,默认为NEAR属性。11FAR型型NEAR型型1 子程序的定义子程序的定义调调用用程程序序和和子子程程序序在在同同一一代代码段中码段中调调用用程程序序和和子子程程序序不不在在同同一一代代码码段中段中子程序的子程序的类型属性类型属性 code segmentcode segment main proc farmain proc far .call subr1call subr1 .ret retmain main endpendpsubr1 proc subr1 proc nearnear .ret retsubr1 subr1 endpendpcode endscode ends segxsegx segment segment subtsubt proc proc farfar .ret ret subtsubt endpendp .call call subtsubt .segxsegx ends ends segysegy segment segment .call call subtsubt .segysegy ends ends 判定技巧子程序只在本代码段中进行调用NEAR类型子程序需要在其它代码段中的调用FAR类型1.2 子程序的类型属性 121 子程序的定义子程序的定义【例1】编写一个子程序,用于显示回车与换行(2)单个字符的显示方法:21号中断号中断2号子功能号子功能(1)回车与换行是字符,且ASCII码分别为:13和和10分析:mov ah,2 ;2号子功能 mov dl,65;AA的ASCII码int 21h ;21号中断 131 子程序的定义子程序的定义crlfprocnearretcrlfendp参考代码movah,2;2号子功能号子功能movdl,13;显示回车显示回车int21h;movah,2;2号子功能号子功能movdl,10;显示换行显示换行int21h;功能:显示回车与换行;功能:显示回车与换行14main()floatx,y,z;x=123.23;y=99.09;/*函数调用函数调用*/z=sum(x,y)printf(“%f”,z);/*函数定义函数定义*/floatsum(a,b)floata,b;returna+b;n问题:子程序如何执行?code segmentmain proc far call crlf retmain endpcrlf proc near retcrlf endpcode ends断点调用调用返回返回152 子程序的调用与返回子程序的调用与返回 2.1 调用指令(CALL)n格式:CALL子程序名n功能:让CPU转去执行子程序中的指令序列。n操作:q保存返回地址保存返回地址(即断点处的段:偏移地址)(即断点处的段:偏移地址)q转子程序转子程序162 子程序的调用与返回子程序的调用与返回n程序返回是程序调用的逆逆操作。n格式:RETn功能:恢复返回地址返回地址,转调用程序的断点处,继续主程序的执行。2.2 返回指令(RET)17 CXCX 操作 执行次数4;初始初始3;子程序中子程序中deccx2;LOOP(cx-1)1;子程序中子程序中deccx0;LOOP(cx-1),结束),结束3 寄存器的保护与恢复【例2】思考:q程序段中子程序执行 多少次?MOV CX,4 S:CALL subp LOOP S 2次次原因:原因:子程序中修改了子程序中修改了CX的值!的值!subp proc near dec cx retsubp endp12183 寄存器的保护与恢复n实现细节:XXXXX PROC RETXXXXX ENDPPOP AX PUSH AXPUSH SI ;子程序使用了子程序使用了 ;AX、SIPOP SI q保护:子程序开始时q恢复:在返回前;影响了标志寄存器影响了标志寄存器PUSHFPOPF193 寄存器的保护与恢复n子程序的结构n优 点:q不会破坏主程序的数据;q增强了子程序的通用性。保护寄存器保护寄存器恢复寄存器恢复寄存器处理部分(核心)处理部分(核心)子程序返回子程序返回204 参数传递参数传递n参数传递:调用程序和子程序之间的信息交互。调用程序调用程序子程序子程序入口参数入口参数出口参数出口参数214 参数传递参数传递常用的参数传递方法常用的参数传递方法用寄存器传递参数用寄存器传递参数约定存储单元传递参数约定存储单元传递参数使用堆栈传递参数使用堆栈传递参数22【例例3】求校验和求校验和n子程序计算数组元素的子程序计算数组元素的“校验和校验和”n校验和是指不记进位的累加校验和是指不记进位的累加入口参数:入口参数:数组的逻辑地址数组的逻辑地址元素个数元素个数出口参数:出口参数:求和结果求和结果4 参数传递参数传递23n把参数存于约定的寄存器中,可以传值,也可把参数存于约定的寄存器中,可以传值,也可以传址。以传址。n子程序对带有出口参数的寄存器不能保护和恢子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护)复(主程序视具体情况进行保护)n子程序对带有入口参数的寄存器可以保护,也子程序对带有入口参数的寄存器可以保护,也可以不保护;但最好一致可以不保护;但最好一致4.1 寄存器传递参数寄存器传递参数调用程序调用程序子程序子程序约定约定寄存器寄存器24【例3-1】入口参数:入口参数:CX元素个数,元素个数,DS:BX数组的段地址:偏移地址数组的段地址:偏移地址出口参数:出口参数:AL校验和校验和;设置入口参数(含有设置入口参数(含有DS数组的段地址)数组的段地址)movbx,offsetarray;BX数组的偏移地址数组的偏移地址movcx,count;CX数组的元素个数数组的元素个数callchecksuma;调用求和过程调用求和过程movresult,al;处理出口参数处理出口参数主程序主程序25checksumachecksuma procprocxorxor al,alal,al;累加器清累加器清0 0sumasuma:add add al,bxal,bx;求和求和inc inc bxbx;指向下一个字节指向下一个字节loop loop sumasumaretretchecksumachecksuma endpendp 子程序子程序264.1 寄存器传递参数寄存器传递参数【例4】编写一个子程序UPPER,实现把寄存器AL中存放的字符变为大写。;子程序功能:把AL中存放的字符变大写;入口参数:AL;出口参数:AL;算法描述:;(1)判断AL中字符是否在az之间;az小写字符(母);(2)规律:a-A=20H(32);转换规则:大写字符=小写字符-20H。274.1 寄存器传递参数寄存器传递参数UPPERPROCNEAR ;是否小写是否小写CMPAL,aJBoverCMPAL,zJAover;小写转大写小写转大写SUBAL,20Hover:RETUPPERENDPn子程序的调用:子程序的调用:;调用前设定入口参数调用前设定入口参数MOVAL,bCALLUPPER;子程序返回时,子程序返回时,(AL)=B;小于则转移小于则转移;大于则转移大于则转移284.1 寄存器传递参数寄存器传递参数 n特点:q简单方便,只需约定寄存器 即可。q寄存器的个数和容量非常有限,适用于传递较少的参数信息。n问题:q参数较多时怎么办?294.2 约定存储单元传递参数约定存储单元传递参数 n特点:q约定存储单元交互信息,即主程序和子程序直接采用同一个变量名共享同一个变量,实现参数的传递q可以在调用程序与子程序间传递大量数据调用程序调用程序子程序子程序约定约定存储存储单元单元30【例例3-2】入口参数:入口参数:count元素个数,元素个数,array数组名(段地址:偏移地址)数组名(段地址:偏移地址)出口参数:出口参数:sum校验和校验和datasegmentarraydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?dataends314.2 约定存储单元传递参数约定存储单元传递参数sump proc nearsump proc near push ax push ax ;寄存器保护寄存器保护 push push cxcx push push si si lea lea si si,arrayarray movmov cxcx,countcount movmov ax,0 ax,0next:add ax,next:add ax,si si add add si si,2,2 loop next loop next ;累加求和累加求和 movmov sumsum,ax,ax pop pop si si ;寄存器恢复寄存器恢复 pop pop cxcx pop ax pop ax ret retsump sump endpendp入口参数入口参数出口参数出口参数;设定入口参数(无)设定入口参数(无)callsump;将累加和送入将累加和送入;DX寄存器中寄存器中movdx,sum324.3 用堆栈传递参数用堆栈传递参数n主程序将子程序的入口参数压入堆栈,子程序从堆主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数栈中取出参数n子程序将出口参数压入堆栈,主程序弹出堆栈取得子程序将出口参数压入堆栈,主程序弹出堆栈取得它们它们n问题问题:子程序的调用也要用到堆栈子程序的调用也要用到堆栈!【例例3-3】入口参数:入口参数:顺序压入偏移地址和元素个数顺序压入偏移地址和元素个数出口参数:出口参数:AL校验和校验和33.startup.startupmovmov ax,ax,offset arrayoffset arraypush axpush axmovmov ax,ax,countcountpush axpush axcallcall checksumcchecksumcadd sp,4add sp,4movmov result,alresult,al.exit 0.exit 0【例例3-3 3-3】主程序主程序图示图示要要注注意意堆堆栈栈的的分分配配情情况况,保保证证参参数数存存取取正正确、子程序正确返回,并保持堆栈平衡确、子程序正确返回,并保持堆栈平衡34checksumcchecksumcprocprocpush push bpbpmovmov bp,spbp,sp;利用利用BPBP间接寻址存取参数间接寻址存取参数push push bxbxpush push cxcxmovmov bx,bp+6 bx,bp+6;SS:BP+6;SS:BP+6指向偏移地址指向偏移地址movmov cx,bp+4 cx,bp+4;SS:BP+4;SS:BP+4指向元素个数指向元素个数xorxor al,alal,alsumcsumc:add add al,bxal,bx inc inc bxbxloop loop sumcsumcpop pop cxcxpop pop bxbxpop pop bpbpretretchecksumcchecksumcendpendp【例例3-3 3-3】子程序子程序图示图示35用寄存器传递参数:用寄存器传递参数:将参数送入约定的寄存器中,将参数送入约定的寄存器中,用于参数较少的情况。用于参数较少的情况。1用堆栈传递参数:用堆栈传递参数:调用程序将参数压入堆栈,子程调用程序将参数压入堆栈,子程序从堆栈中取得参数。用于参数多、子程序嵌套调序从堆栈中取得参数。用于参数多、子程序嵌套调用和递归调用用和递归调用 。3用参数表传递参数:用参数表传递参数:调用程序将参数组成一个参数调用程序将参数组成一个参数表传送给子程序,用于大量参数的传送。表传送给子程序,用于大量参数的传送。24 参数传递参数传递更多的情况,是根据具体需要对参数传递方式进行 组合使用。参数传递小结参数传递小结375 子程序的嵌套子程序的嵌套子程序内包含有子程序子程序内包含有子程序的调用就是子程序嵌套的调用就是子程序嵌套没有什么特殊要求没有什么特殊要求38ALdispALdispprocprocpush axpush axpush push cxcx;实现实现alal内容的显示内容的显示push axpush ax;暂存暂存axaxmovmov cl,4 cl,4shrshr al,clal,cl;转换转换alal的高的高4 4位位call call htoaschtoasc;子程序调用(嵌套)子程序调用(嵌套)pop axpop ax;转换转换alal的低的低4 4位位call call htoaschtoasc;子程序调用(嵌套)子程序调用(嵌套)pop pop cxcxpop axpop axretretALdispALdispendpendp【例例5 5】嵌套子程序嵌套子程序1/31/339;将将ALAL低低4 4位表达的一位位表达的一位1616进制数转换为进制数转换为ASCIIASCII码码HTOASCHTOASC procprocpush axpush axpush push bxbxpush push dxdxmovmov bxbx,offset,offset ASCII;BX ASCII;BX指向指向ASCIIASCII码表码表and al,0fhand al,0fh;取得一位取得一位1616进制数进制数xlatxlat ASCII ASCII;换码:换码:ALCS:BXALCS:BXALAL,注意数据在代码段,注意数据在代码段CSCS【例例5 5】嵌套子程序嵌套子程序2/32/340movmov dl,aldl,al;显示显示movmov ah,2 ah,2intint 21h 21hpop pop dxdxpop pop bxbxpop axpop axretret;子程序返回子程序返回;子程序的数据区子程序的数据区ASCIIASCIIdb 30h,31h,32h,33h,34h,35h,36h,37hdb 30h,31h,32h,33h,34h,35h,36h,37hdb 38h,39h,41h,42h,43h,44h,45h,46hdb 38h,39h,41h,42h,43h,44h,45h,46hHTOASCHTOASC endpendp【例例5 5】嵌套子程序嵌套子程序3/33/341子程序的递归子程序的递归n当子程序直接或间接地嵌套调用自身时称为递归调用递归调用,含有递归调用的子程序称为递归子程序递归子程序n递归子程序必须采用寄存器寄存器或堆栈堆栈传递参数,递归深度受堆栈空间的限制42子程序的递归子程序的递归【例6】:求阶乘;参数传递参数传递;计算计算N!N!的近过程的近过程factfact;入口参数:入口参数:压入压入 N N;出口参数:出口参数:弹出弹出 N!N!43.model small.model small.stack 256.stack 256.data.dataN Ndwdw 3 3resultresultdwdw?.code.code.startup.startupmovmov bx,Nbx,Npush push bxbx;入口参数:入口参数:N Ncall factcall fact;调用递归子程序调用递归子程序pop resultpop result;出口参数:出口参数:N N!.exit 0.exit 0【例例6 6】主程序主程序1/31/3图示图示44;计算计算N!N!的近过程的近过程;入口参数:入口参数:压入压入 N N;出口参数:出口参数:弹出弹出 N!N!fact fact procprocpush axpush axpush push bpbpmovmov bp,spbp,spmovmov ax,bp+6;ax,bp+6;取入口参数取入口参数 N Ncmpcmp ax,0 ax,0jnejne fact1 fact1;N;N0,N!0,N!N N(N-1)!(N-1)!inc axinc ax;N;N0,N!0,N!1 1jmpjmp fact2 fact2【例例6 6】递归子程序递归子程序2/32/3图示图示45fact1:fact1:decdec ax ax;N-1;N-1push axpush axcall factcall fact;调用递归子程序求调用递归子程序求(N-1)!(N-1)!pop axpop axmulmul word word ptrptr bp+6 bp+6;求求 N N(N-1)!(N-1)!fact2:fact2:movmov bp+6,ax bp+6,ax;存入出口参数存入出口参数 N!N!pop pop bpbppop axpop axretretfactfactendpendp【例例6 6】递归子程序递归子程序3/33/3图示图示46子程序的重入子程序的重入n子程序的重入子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。在子程序中,注意利用寄存器和堆栈传递参数和存放临时数据,而不要使用固定的存储单元(变量),就能够实现重入。n子程序的重入不同于子程序的递归。重入是被动地进入,而递归是主动地进入;重入的调用间往往没有关系,而递归的调用间却是密切相关的。递归子程序也是可重入子程序。48【例例7 7】:从键盘输入有符号十进制数:从键盘输入有符号十进制数n子程序从键盘输入一个有符号十进制数;子程序还包含将ASCII码转换为二进制数的过程n输入时,负数用“”引导,正数直接输入或用“”引导n子程序用寄存器传递出口参数寄存器传递出口参数,主程序调用该子程序输入10个数据转换算法转换算法DEMO4-13DEMO4-1349.data.datacountcount=10=10arrayarraydwdw count dup(0)count dup(0);预留数据存储空间预留数据存储空间.code.code.startup.startupmovmov cx,countcx,countmovmov bx,offsetbx,offset array arrayagain:again:call readcall read;调用子程序输入一个数据调用子程序输入一个数据movmov bx,axbx,ax;将出口参数存放缓冲区将出口参数存放缓冲区inc inc bxbxinc inc bxbxcall call dpcrlfdpcrlf;调用子程序,光标回车换行以便输入下一个数据调用子程序,光标回车换行以便输入下一个数据loop againloop again.exit 0.exit 050;功能:输入有符号功能:输入有符号1010进制数的通用子程序进制数的通用子程序;入口参数:无入口参数:无;出口参数:出口参数:AXAX补码表示的二进制数值补码表示的二进制数值;说明:负数用说明:负数用“”引导,正数用引导,正数用“”引导或引导或直接输入;数据范围是直接输入;数据范围是32767327673276832768readreadprocprocpush push bxbxpush push cxcxpush push dxdxxorxor bx,bxbx,bx;BX;BX保存结果保存结果xorxor cx,cxcx,cx;CXCX为正负标志为正负标志,0 0为正,为正,1 1为负为负movmov ah,1 ah,1;输入一个字符输入一个字符intint 21h 21h51cmpcmp al,al,+;是是“”,继续输入字符,继续输入字符jzjz read1 read1cmpcmp al,al,-;是是“”,设置,设置1 1标志标志jnzjnz read2 read2;非非“”和和“”,转,转read2read2movmov cx,-1 cx,-1read1:read1:movmov ah,1 ah,1;继续输入字符继续输入字符intint 21h 21hread2:read2:cmpcmp al,al,0 0;不是不是0 09 9之间的字符,则输入数据结束之间的字符,则输入数据结束jbjb read3 read3cmpcmp al,al,99jaja read3 read3转换算法转换算法52sub al,30hsub al,30h;是是0 09 9之间的字符,则转换为二进制数之间的字符,则转换为二进制数;利用移位指令,实现数值乘利用移位指令,实现数值乘1010:BXBXBXBX1010shlshl bx,1 bx,1movmov dx,bxdx,bxshlshl bx,1 bx,1shlshl bx,1 bx,1add add bx,dxbx,dx;movmov ah,0 ah,0add add bx,axbx,ax;已输入数值乘已输入数值乘1010后,与新输入数值相加后,与新输入数值相加jmpjmp read1 read1;继续输入字符继续输入字符转换算法转换算法53read3:read3:cmpcmp cx,0 cx,0jzjz read4 read4negneg bxbx;是负数,进行求补是负数,进行求补read4:read4:movmov ax,bxax,bx;设置出口参数设置出口参数pop pop dxdxpop pop cxcxpop pop bxbxretret;子程序返回子程序返回readreadendpendp;使光标回车换行的子程序使光标回车换行的子程序dpcrlfdpcrlfprocproc.;省略省略dpcrlfdpcrlfendpendpendend54【例例8 8】:显示有符号十进制数:显示有符号十进制数n子程序在屏幕上显示一个有符号十进制数;子程序还包含将二进制数转换为ASCII码的过程n显示时,负数用“”引导,正数直接输出、没有前导字符n子程序的入口参数用共享变量传递的入口参数用共享变量传递,主程序调用该子程序显示10个数据转换算法转换算法动画动画lt4-14lt4-14DEMO4-14DEMO4-1456.data.datacountcount=10=10arrayarraydwdw 1234,-1234,0,1,-1,32767 1234,-1234,0,1,-1,32767dwdw-32768,5678,-5678,9000-32768,5678,-5678,9000wtempwtempdwdw?;共享变量共享变量.code.code.startup.startupmovmov cx,countcx,countmovmov bx,offsetbx,offset array arrayagain:again:movmov ax,bxax,bx movmov wtempwtemp,ax,ax;将入口参数存入共享变量将入口参数存入共享变量call writecall write;调用子程序显示一个数据调用子程序显示一个数据inc inc bxbxinc inc bxbxcall call dpcrlfdpcrlf;便于显示下一个数据便于显示下一个数据loop againloop again.exit 0.exit 057;显示有符号显示有符号1010进制数的通用子程序进制数的通用子程序;入口参数:入口参数:共享变量共享变量wtempwtempwritewriteprocprocpush axpush axpush push bxbxpush push dxdxmovmov ax,ax,wtempwtemp;取出显示数据取出显示数据test test ax,axax,ax;判断零、正数或负数判断零、正数或负数jnzjnz write1 write1movmov dl,dl,00;是零,显示是零,显示“0 0”后退出后退出movmov ah,2 ah,2intint 21h 21hjmpjmp write5 write558write1:write1:jnsjns write2 write2;是负数,是负数,显示显示“”movmov bx,axbx,ax;AX;AX数据暂存于数据暂存于BXBXmovmov dl,dl,-movmov ah,2 ah,2intint 21h 21hmovmov ax,bxax,bxnegneg ax ax;数据求补(求绝对值)数据求补(求绝对值)write2:write2:movmov bx,10 bx,10push push bxbx;1010压入堆栈,作为退出标志压入堆栈,作为退出标志转换算法转换算法59write3:write3:cmpcmp ax,0 ax,0;数据(余数)为零数据(余数)为零jzjz write4 write4;转向显示转向显示sub sub dx,dxdx,dx;扩展被除数扩展被除数DX.AXDX.AXdiv div bxbx;数据除以数据除以1010:DX.AXDX.AX1010add dl,30hadd dl,30h;余数(余数(0 09 9)转换为)转换为ASCIIASCII码码push push dxdx;数据各位数据各位先低位后高位压入堆栈先低位后高位压入堆栈jmpjmp write3 write3write4:write4:pop pop dxdx;数据各位数据各位先高位后低位弹出堆栈先高位后低位弹出堆栈cmpcmp dl,10 dl,10;是结束标志是结束标志1010,则退出,则退出jeje write5 write5转换算法转换算法60movmov ah,2 ah,2;进行显示进行显示intint 21h 21hjmpjmp write4 write4write5:write5:pop pop dxdxpop pop bxbxpop axpop axretret;子程序返回子程序返回writewriteendpendp;使光标回车换行的子程序使光标回车换行的子程序dpcrlfdpcrlfprocproc.;省略省略dpcrlfdpcrlfendpendpendend61课程设计课程设计n编写一个程序,实现:q输入一个十进制数q输出一个十进制数n进制转换练习q采用菜单方式选择,实现进制转换二二二二八八八八十六十六十六十六十十十十DEMO kcsj4-1DEMO kcsj4-163【例例9 9】:计算有符号数平均值:计算有符号数平均值n子程序将16位有符号二进制数求和,然后除以数据个数得到平均值n子程序的入口参数利用堆栈传递入口参数利用堆栈传递,主程序需要压入数据个数数据个数和数据缓冲区的偏移地址数据缓冲区的偏移地址。子程序通过BP寄存器从堆栈段相应位置取出参数n子程序的出口参数用寄存器出口参数用寄存器AX传递传递n主程序提供10个数据,并保存平均值避免溢出避免溢出DEMO4-15DEMO4-1564.data.datacountcount=10=10arrayarraydwdw 1234,-1234,0,1,-1,32767 1234,-1234,0,1,-1,32767dwdw-32768,5678,-5678,9000-32768,5678,-5678,9000wmedwmeddwdw?;存放平均值存放平均值.code.code.startup.startupmovmov ax,countax,countpushpush ax ax;压入数据个数压入数据个数movmov ax,offsetax,offset array arraypushpush ax ax;压入缓冲区偏移地址压入缓冲区偏移地址call meancall mean;调用子程序求平均值调用子程序求平均值add sp+4add sp+4;平衡堆栈平衡堆栈movmov wmed,axwmed,ax;保存平均值(不含余数)保存平均值(不含余数).exit 0.exit 065;计算计算1616位有符号数平均值子程序位有符号数平均值子程序;入口参数入口参数:顺序压入数据个数和缓冲区偏移地址:顺序压入数据个数和缓冲区偏移地址;出口参数:出口参数:AXAX平均值平均值meanmeanprocprocpush push bpbpmovmov bp,spbp,sppush push bxbx;保护寄存器保护寄存器push push cxcxpush push dxdxpush push sisipush push didi66movmov bx bx,bp+4,bp+4 ;从堆栈取出偏移地址从堆栈取出偏移地址movmov cx cx,bp+6,bp+6 ;从堆栈取数据个数从堆栈取数据个数xorxor si,sisi,si;SI;SI保存求和的低保存求和的低1616位值位值movmov di,sidi,si;DI;DI保存求和的高保存求和的高1616位值位值mean1:mean1:movmov ax,bxax,bx ;取出一个数据取出一个数据AXAXcwdcwd;符号扩展符号扩展DXDXadd add si,axsi,ax;求和低求和低1616位位adcadc di,dxdi,dx;求和高求和高1616位位inc inc bxbx;指向下一个数据指向下一个数据inc inc bxbxloop mean1loop mean1;循环循环堆栈区堆栈区避免溢出避免溢出67movmov ax,siax,simovmov dx,didx,di;累加和在累加和在DX.AXDX.AXmovmov cx,bp+6 cx,bp+6;数据个数在数据个数在CXCXidividiv cxcx;有符号数除法,求的平均值在有符号数除法,求的平均值在AXAX中、余数在中、余数在DXDX中中pop pop didi;恢复寄存器恢复寄存器pop pop sisipop pop dxdxpop pop cxcxpop pop bxbxpop pop bpbpretretmeanmeanendpendpendend68小小 结结熟练掌握熟练掌握1)转移指令转移指令(条件转移和无条件转移和无条件转移指令条件转移指令)3)循环指令循环指令及循环程序设计及循环程序设计4)循环指令循环指令及循环及循环程序设计程序设计 5)子程序设计子程序设计2)分支程序设计分支程序设计71第第4章章 教学要求教学要求n1.掌握基本程序结构顺序结构、分支结构、循环结构、子程序及其汇编语言程序设计n2.熟悉常见程序设计问题:多精度运算、查表(查代码、特定值等)ASCII、BCD及十六进制数据间的代码转换数据范围判断(09、AZ、az)字母大小写转换;字符串传送、比较等操作求最小最大值、数据求和、统计字符个数子程序的寄存器和共享变量传递参数72n作业:qP125:N4-18,N4-27 n上机练习:qP125:4-10 4-15 4-16 q 4-19 4-28 4-2973