分享
分销 收藏 举报 申诉 / 42

类型第6章子程序结构.ppt

  • 上传人:w****g
  • 文档编号:14656265
  • 上传时间:2026-10-26
  • 格式:PPT
  • 页数:42
  • 大小:556.54KB
  • 下载积分:10 金币
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    章子 程序结构
    资源描述:
    单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,ch6,*,计算机科学与技术系,汇编语言,在程序设计中,我们会发现一些,多次无规律重复的程序段或语句序列,。解决此类问题一个行之有效的方法就是将它们设计成,可供反复调用的独立的子程序结构,,以便在需要时调用。在汇编语言中,子程序又称过程,。,调用子程序的程序称为主调程序或主程序,。,第6章 子程序结构,10/26/2026,1,ch6,子程序的基本结构包括以下几个部分:,(1)子程序定义,(2)保护现场和恢复现场,(3)子程序体,(4)子程序返回,子程序的结构,10/26/2026,2,ch6,子程序的定义是由过程定义伪指令PROC和ENDP来完成的。其格式如下:,过程名 PROC NEAR/FAR,过程名 ENDP,其中PROC表示过程定义开始,ENDP表示过程定义结束。,过程名是过程入口地址的符号表示,。,一般过程名同标号一样,具有三种属性,即段属性、偏移地址属性以及类型属性(NEAR 和 FAR),。,6.1.1 子程序的定义,6.1 子程序的设计方法,10/26/2026,3,ch6,如果调用程序和过程在,同一代码段,中,则使用,NEAR属性,;,MAIN PROC FAR,CALL SUBR1,RET,MAIN ENDP,;,SUBR1 PROC,NEAR,RET,SUBR1 ENDP,MAIN PROC FAR,CALL SUBR1,RET,SUBR1 PROC,NEAR,RET,SUBR1 ENDP,MAIN ENDP,6.1.2 子程序的调用和返回,10/26/2026,4,ch6,如果,调用程序和过程不在同一代码段中,,则使用,FAR,属性;,SEGX SEGMENT,SUBT PROC,FAR,RET,SUBT ENDP,CALL SUBT,SEGX ENDS,;,SEGY SEGMENT,CALL SUBT,SEGY ENDS,10/26/2026,5,ch6,Decihex segment,assume cs:Decihex,Main proc far,Repeat:push ds,xor ax,ax,push ax,call decibin,call crlf,call binihex,call crlf,ret,Main endp,Decibin proc near,mov bx,0,Newchar:mov ah,1,int 21h,sub al,30h,jl exit,cmp al,9,jg exit,cbw,xchg ax,bx,mov cx,10,mul cx,xchg ax,bx,;每次乘的,add bx,ax,;结果在BX中,jmp newchar,Exit:ret,Decibin endp,10/26/2026,8,ch6,Binihex proc near,mov ch,4,Rotate:mov cl,4,rol bx,cl,mov dl,bl,and dl,0fh,add dl,30h,cmp dl,3ah,jl print,add dl,7h,Print:mov ah,2,int 21h,dec ch,jnz rotate,ret,Binihex endp,Crlf proc near,mov ah,2,mov dl,odh,int 21h,mov dl,oah,int 21h,ret,Crlf endp,Decihex ends,end repeat,10/26/2026,9,ch6,如果过程和调用过程在同一源文件(同一模块)中,则过程可直接访问模块中的变量。,例,6.4,主程序,MAIN,和过程,PROADD,在同一源文件中,要求用过程,PROADD,累加数组的所有元素,并把和(不考虑溢出的可能性)送到指定的存储单元中去,10/26/2026,10,ch6,DATA SEGMENT,ARY,DW 100 DUP(?),COUNT,DW 100,SUM,DW?,DATA ENDS,CODE SEGMENT,MAIN PROC FAR,ASSUME CS:CODE,DS:DATA,START:PUSH DS,SUB AX,AX,PUSH AX,MOV AX,DATA,CALL NEAR PTR PROADD,RET,MAIN ENDP,PROADD PROC NEAR,PUSH AX,PUSH CX,PUSH SI,PUSH DI,LEA SI,ARY,MOV CX,COUNT,XOR AX,AX,NEXT:ADD AX,SI,ADD SI,2,LOOP NEXT,MOV,SUM,AX,POP DI,POP SI,POP CX,POP AX,RET,PROADD ENDP,CODE ENDS,END START,10/26/2026,11,ch6,CODE SEGMENT,ARY DW 100 DUP(?),COUNT DW 100,SUM DW?,NUM DW 100 DUP(?),N DW 100,TOTAL DW?,;,MOV TABLE,OFFSET ARY,MOV TABLE+2,OFFSET COUNT,MOV TABLE+4,OFFSET SUN,MOV BX,OFFSET TABLE,CALL PROADD ;计算SUM,PROADD PROC NEAR,PUSH AX,PUSH CX,PUSH SI,MOV SI,MOV CX,MOV DI,XOR AX,AX,NEXT:ADD AX,SI,ADD SI,2,LOOP NEXT,MOV ,AX,POP SI,POP CX,POP AX,RET,PROADD ENDP,CODE ENDS,END START,BX,BX+2,BX+4,DI,3 通过地址表传递参数,10/26/2026,12,ch6,例:把内存中字变量num的值,转换为4个用ASC码表示的16进制数码,串的起始地址为string,。,Data segment,Num dw 25afh,String db 4 dup(?),$,0dh,0ah,Data ends,Stack segment para stack stack,db 100 dup(?),Stack ends,Code segment,assume cs:code,ds:data,ss:stack,Main proc far,Begin:push ds,xor ax,ax,push ax,mov ax,data,mov ds,ax,lea bx,string,push,bx,push num,call binhex,lea dx,string,mov ah,9,int 21h,ret,Main endp,2000:0000,2000:0002,3000:0000,3000:0001,3000:0003,3000:0004,3000:0007,3000:0009,3000:000d,3000:000e,3000:0012,3000:0015,3000:0019,15,00,af,25,02,00,sp,string地址,Num,Lea dx,string,地址(IP),4 通过堆栈传递地址或参数,10/26/2026,13,ch6,Binhex proc near,push bp,mov bp,sp,push ax,push di,push bx,push cx,pushf,mov ax,bp+4,;ax=25afh,mov di,bp+6,;di=0002,mov ch,4,mov cl,4,roat:rol ax,cl,mov bl,al,and bl,0fh,add bl,30h,cmp bl,39h,jle next,add bl,7h,0015,25af,0002,sp,string地址,Num,Lea dx,string地址(IP),flag,cx,bx,di,ax,bp,(Sp),bp,bp+2,bp+4,bp+6,Bp-6,Bp-4,Bp-2,10/26/2026,14,ch6,Next:mov di,bl,inc di,dec ch,jnz rota,popf,pop cx,pop bx,pop di,pop ax,pop bp,ret 4,Binhex endp,Code ends,end begin,0015,25af,0002,sp,string地址,Num,Lea dx,string地址(IP),flag,cx,bx,di,ax,bp,sp,10/26/2026,15,ch6,例3:求10个数的累加值.,-远调用,Data segment,Ary db 10 dup(?),Count db 10,Sum db?,Data ends,Stack segmen,t,para stack stack,db 100 dup(?),Stack ends,Code1 segment,assume cs:code1,ds:data,ss;stack,Main proc far,Start:push ds,xor ax,ax,push ax,mov ax,data,mov ds,ax,10/26/2026,16,ch6,Mov bx,offset ary,Push bx,Mov bx,offset count,Push bx,Mov bx,offset sum,Push bx,Call far ptr proadd,mov al,sum,mov dl,al,mov ah,2,int 21h,ret,Main endp,Code1 ends,Sum地址,Count地址,Ary地址,MOV AL,SUM 地址,sp,IP,CS,10/26/2026,17,ch6,Sum地址,Count地址,Ary地址,sp,MOV AL,SUM 地址,di,si,cx,ax,bp,(Sp),bp,IP,CS,Code2 segment,assume cs:code2,Proadd proc far,push bp,mov bp,sp,push ax,push cx,push si,push di,mov si,bp+0ah,mov di,bp+08h,mov cl,di,mov di,bp+06h,xor al,al,Again:add al,si,inc si,dec cl,jnz again,mov di,al,pop di,pop si,pop cx,pop ax,pop bp,ret 6,Proadd endp,Code2 ends,end start,bp+0ah,bp+08h,bp+06h,10/26/2026,18,ch6,(1)PUBLIC伪指令,格式:,PUBLIC 符号,符号,功能:说明其后的符号是全局符号。全局符号能被其他模块引用。(局部符号),(2)EXTRN伪指令,格式:,EXTRN 符号:类型,符号:类型,功能:说明在本模块中需要引用的、由其他模块定义的符号,即外部符号,。,5 多个模块之间的参数传送问题,10/26/2026,19,ch6,source module 1,extrn a:word,Data1 segment,b dw?,Data1 ends,code1 segment,assume cs:code1,ds:data1,Main proc far,start:mov ax,data1,mov ds,ax,mov ah,4ch,int 21h,Main endp,Code1 ends,End start,source module 2,public a,Data2 segment,a dw?,Data2 ends,code2 segment,assume cs:code2,ds:data2,Main proc far,start:mov ax,data2,mov ds,ax,mov ah,4ch,int 21h,Main endp,Code2 ends,End start,注意:,应先有public 定义,然后才有extrn说明,10/26/2026,20,ch6,NAMEMOD1,EXTRNDISP,:,FAR,PUBLICSTR1,,,N,,,BUF,DATA1SEGMENT,STR1DB,HOW DO YOU DO?,N=$-STR1,BUFDB,THIS IS AN EXAMPLE OF MODULES PROGRAM,DATAENDS,STACKSEGMENT STACK,DB 200 DUP,(,0,),STACKENDS,CODE1SEGMENT,ASSUME CS,:,CODE1,,,DS,:,DATA1,,,SS,:,STACK,START,:,MOVAX,,,DATA,MOVDS,,,AX,CALLDISP,MOVAH,,,4CH,INT21H,CODE1ENDS,ENDSTART,例:用模块化程序设计方法建立两个模块MOD1 ASM和MOD2 ASM的数据通讯。,10/26/2026,21,ch6,NAMEMOD2,EXTRNSTR1,:,BYTE,,,STR2,:,BYTE,,,N,:,ABS,PUBCICDISP,DATA2SEGMENT,STR2DB 81 DUP,(,0,),DATA2ENDS,CODE2SEGMENT,ASSUME CS,:,CODE2,,,ES,:,DATA2,DISPPROCFAR,MOVAX,,,DATA2,MOVES,,,AX,LEABX,,,STR1,MOVCX,,,N,LEASI,,,STR2,NEXT,:,MOVAL,,,BX,MOVES,:,SI,,,AL,INCBX,INCSI,LOOPNEXT,LEADX,,,BUF,MOVAH,,,9,INT21H,RET,DISPENDP,CODE2ENDS,END,10/26/2026,22,ch6,6.1.5 增强功能的过程定义伪操作,Procname PROC,attributes field,USER,register list,parameter field,Procname ENDP,Attributes field(属性字段),包括:,Distance,:,near 、far,Language type,:说明是那种高级语言的子程序 如,pascal、c,等。,Visibility,:说明程序的可见性 是,private,或是,public,。,Prologue,:是一个,宏的名字,,允许用宏来控制过程的入口或出口有关的代码,USER,:该字段用来,指定用户所需保存和恢复的寄存器表,。,Parameter field,:参数字段,,允许用户指定该过程所用的参数,。,标识符:类型,标识符:类型,10/26/2026,23,ch6,Data segment,Ary,db 10 dup(?),Count,db 10,Sum,db?,Data ends,Stack segmen,t,para stack stack,db 100 dup(?),Stack ends,Code1 segment,assume cs:code1,ds:data,ss:stack,Main proc far,Start:push ds,xor ax,ax,push ax,mov ax,data,mov ds,ax,Mov bx,offset,ary,Push bx,Mov bx,offset,count,Push bx,Mov bx,offset,sum,Push bx,Call far ptr proadd,mov al,sum,mov dl,al,mov ah,2,int 21h,ret,Main endp,Code1 ends,例6.4,用增强功能过程定义伪操作实现,10/26/2026,24,ch6,Code2 segment,assume cs:code2,Proadd proc far,push bp,mov bp,sp,push ax,push cx,push si,push di,mov si,bp+0ah,mov di,bp+08h,mov cl,di,mov di,bp+06h,xor al,al,Again:add al,si,inc si,dec cl,jnz again,mov di,al,pop di,pop si,pop cx,pop ax,pop bp,ret 6,Proadd endp,Code2 ends,end start,Code2 segment,assume cs:code2,Proadd proc,pascal,user,ax cx si di,para,:,word,parc,:,word,pars,:,word,mov si,para,mov di,parc,mov cl,di,mov di,pars,xor al,al,Again:add al,si,inc si,dec cl,jnz again,mov di,al,ret,Proadd endp,Code2 ends,end start,Sum地址,Count地址,Ary地址,(bp),IP,CS,(,bp,+2),(,bp,+4),(,bp,+6,),(,bp,+8,),(,bp,+a,),原始bp,mov al,sum,para,pars,parc,局部变量,di,si,cx,ax,(,bp,-2),10/26/2026,25,ch6,增强功能的过程定义伪操作除了以上功能外,,还可以在过程中定义局部变量,。,局部变量是在过程内部使用的变量,他是在过程调用是在堆栈中建立的,在退出过程是被释放,。,可以用 LOCAL 定义,LOCAL 变量:类型,变量:类型,Sum地址,Count地址,Ary地址,(bp),IP,CS,(,bp,+2),(,bp,+4),(,bp,+6),(,bp,+8),(,bp,+a),原始bp,(,bp,-2,),(,bp,-4,),局部变量,10/26/2026,26,ch6,6.2 子程序的嵌套,一个子程序可以作为调用程序去掉用另一个子程序,这种情况称为子程序的嵌套,。嵌套深度不限。,但应注意什么问题?,堆栈溢出:上溢、下溢,递归子程序:,如果一个子程序调用的是子程序的本身,就是递 归子程序。,10/26/2026,27,ch6,例5:计算 N!=N*(N-1)*(N-2)*1,-递归子程序,Data segment,Num db 3,Result dw?,Data ends,Stack segment para stack stack,db 100 dup(?),Stack ends,Code segment,assume cs:code,ds:data,ss:stack,Main proc far,Begin:push ds,xor ax,ax,push ax,mov ax,data,mov ds,ax,10/26/2026,28,ch6,mov ah,0,mov al,num,call factor,mov result,ax,ret,Main endp,Factor proc,push ax,sub ax,1,jne f_cont,pop ax,jmp return,f_cont:,call factor,pop cx,mul cl,return:ret,factor endp,Code ends,end begin,IP,1,Mov result,ax 地址,3,IP,2,Pop cx 地址,2,IP,3,Pop cx 地址,1,ax=1,IP,POP CX,地址,cx=2,ax*cx=1*2,IP,POP CX,地址,cx=3,ax*cx=1*2*3,IP,Mov result,ax,地址,10/26/2026,29,ch6,常用的,DOS,系统功能调用,1单字符输入(1号调用),2单字符显示(2号调用),3打印输出(5号调用),4结束调用(4CH号调用),5显示字符串(9号调用),6字符串输入(10号调用),10/26/2026,30,ch6,1单字符输入(1号调用),格式:,MOVAH,1,INT21H,功能:从键盘输入字符的ASCII码送入寄存器AL中,并送显示器显示。,2单字符显示(2号调用),格式:,MOV DL,待显示字符的ASCII码,MOV AH,2,INT 21H,功能:将DL寄存器中的字符送显示器显示.,10/26/2026,31,ch6,3打印输出(5号调用),格式:,MOVDL,待打印字符的ASCII码,MOVAH,5,INT21H,功能:将DL寄存器中的字符送打印机打印。,4结束调用(4CH号调用),格式:,MOVAH,4CH,INT21H,功能:终止当前程序并返回调用程序。,10/26/2026,32,ch6,5显示字符串(9号调用),格式:LEADX,待显示字符串首偏移地址,MOVAH,9,INT21H,功能:将当前数据区中以,结尾的字符串送显示器显示。,6字符串输入(10号调用),格式:LEADX,缓冲区首偏移地址,MOVAH,10,INT21H,功能:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示器显示。,maxlen db 32,actlen db?,string db 32 dup(?),lea dx,maxlen,mov ah,0ah,int 21h,说明:缓冲区的第一个字节保存最大字符数,这个最,大字符数由用户程序给出。如果键入的字符数,比此数大,机器发出嘟嘟声。第二个字节存放,实际输入的字节数,这个不是由用户填入的而,由功能A填入的。在这两个字节之后,才是我们,输入的字符串。,10/26/2026,33,ch6,6.3 子程序举例,例1:HEXIDEX是一个十六进制数转换成十进制数的程序。要求把从键盘输入的0 FFFFH的十六进制正数转换为十进制数并在屏幕上显示出来。,Display equ 2h,Key equ 1h,Doscall equ 21h,Hexidec segment,Main proc far,assume cs:hexidec,Start:,push ds,sub ax,ax,push ax,call hexidec,call crlf,call binidec,call crlf,jmp main,ret,main endp,Crlf proc near,mov dl,0ah,mov ah,display,int boscall,mov dl,0dh,mov ah,display,int doscall,ret,crlf endp,Hexidec ends,end start,10/26/2026,34,ch6,Hexidec proc near,mov bx,0,Newchar:mov key_in,int doscall,sub al,30h,jl exit,cmp al,10d,jl add_to,sub al,27h,cmp al,0ah,jl exit,cmp ah,10h,jge exit,Add_to:mov cl,4,shl bx,cl,mov ah,0,add bx,ax,jmp,Exit:,Ret,Hexidec endp,Binidec proc near,mov cx,10000d,call dec_div,mov cx,1000d,call dec_div,mov cx,100d,call dec_div,mov cx,10d,call dec_div,mov cx,1d,call dec_div,ret,Dec_div proc near,mov ax,bx,mov dx,0,div cx,mov bx,dx,mov dl,al,add dl,30h,mov ah,display,int doscall,ret,dec_div endp,Binidec endp,10/26/2026,35,ch6,例2:一个简单的信息检索系统。在数据区里,有10个不同的信息,编号为09,每个信息包括30个字符。现在要编制一个程序:从键盘接收09之间的一个编号,然后在屏幕上显示相应编号的信息的内容。,Datarea segment,thirty db 30,msg0 db 0 I like my IBM-PC-,msg1 db 1 I like my IBM-PC-,msg2 db 2 I like my IBM-PC-,msg3 db 3 I like my IBM-PC-,msg4 db 4 I like my IBM-PC-,msg5 db 5 I like my IBM-PC-,msg6 db 6 I like my IBM-PC-,msg7 db 7 I like my IBM-PC-,msg8 db 8 I like my IBM-PC-,msg9 db 9 I like my IBM-PC-,errmsg db error!Invalid praameter,Datarea ends,10/26/2026,36,ch6,Stack segment,db 256 dup(0),tos lable word,Stack ends,Prognam segment,assume cs:prognam,ds:datarea,ss:stack,Start:push ds,xor ax,ax,push ax,mov ax,stack,mov ss,ax,mov ax,datarea,mov ds,ax,mov sp,offset tos,Begin:mov ah,1,int 21h,sub al,0,jc error,cmp al,9,ja error,Mov bx,offset msg0,Mul thirty,Add bx,ax,Call display,Jmp begin,Error:mov bx,offset errmsg,call display,ret,Display proc near,mov cx,30,mov dl,bx,call dispchar,inc bx,loop disp1,mov dl,0dh,call dispchar,mov dl,0ah,call dispchar,ret,Dispchar endp,Dispchar proc naer,mov ah,2,int 21h,ret,Dispchar endp,Main endp,Prognam ends,End start,10/26/2026,37,ch6,例3:,人名排序程序。先从终端键入最多30个人名,当所有人名都进入后,按字母上升的次序将人名排序,并在屏幕上显示已经排好的人名。,10/26/2026,38,ch6,Data segment,namepar label byte,maxnlen db 21,namelen db?,namefld db 21 dup(?),crlf db 13,10,$,endaddr dw?,messg1 db name?,$”,messg2 db sorted names,13,10,$,namectr db 0,nametab db 30 dup(20 dup(),namesav db 20 dup(?),13,10,$,swapped db 0,Data ends,Code segment,main proc far,assume cs:code,ds:data,es:data,start:push ds,mov ax,0,push ax,mov ax,data,mov ds,ax,mov es,ax,cld,lea di,nametab,a20loop:call b10read,cmp namelen,0,jz a30,cmp namectr,30,je a30,call d10stor,jmp a20loop,a30:cmp namectr,1,jbe a40,call g10sort,call k10disp a40:mov ah,4ch,Int 21h,Main endp,10/26/2026,39,ch6,b10read proc near,mov ah,09,lea dx,messg1,int 21h,mov ah,0ah,lea dx,namepar,int 21h,mov ah,09h,lea dx crlf,Int 21h,mov bx,0,mov bl,namelen,mov cx,21,sub cx,bx,b20:mov namefldbx,20h,inc bx,loop b20,ret,b10read endp,d10stor proc near,inc namectr,cld,lea si,namectr,mov cx,10,rep movsw,ret,p10stor endp,g10sort proc near,sub di,40,mov endaddr,di,g20:mov swapped,0,lea si,nametab,g30:mov cx,20,mov di,si,add di,20,add ax,di,mov ax,di,mov bx,si,repe cmpsb,jbe g40,call h10 xchg,g40:mov si,ax,cmp swapped,0,jnz g20,ret,G10sort endp,10/26/2026,40,ch6,h10 xchg proc near,mov cx,10,lea di,namesav,mov si,bx,rep movsw,mov cx,10,mov di,bx,rep movsw,mov cx,10,lea si,namesav,rep movsw,mov swapped,1,ret,h10 xchg endp,k10disp proc near,mov ah,09,lea dx,messg2,int 21h,lea si,nametab,lea di,namesav,mov cx,10,rep movsw,mov ah,09,lea dx,namesav,int 21h,dec namectr,jnz k20,ret,K10disp endp,end start,10/26/2026,41,ch6,第六章 作业,6.1,6.2,6.3,6.7,10/26/2026,42,ch6,
    展开阅读全文

    开通VIP折扣优惠下载文档

    提示  咨信网声明:本文档由用户上传并分享,仅供学习交流、研究之用,未经授权,严禁复制、发行、汇编、翻译或网络传播等,侵权必究。

    咨信网小贴示:
    1、浏览或下载可查看了解,请点击【咨信网告知】。
    2、下载文件中如有侵权或不适当内容,将立即纠正。
    3、如果因为网速或其他原因下载失败请重新下载,重复下载[60天内]不扣币。
    4、开具发票登录电脑端申请,请点击【索取发票】。

    咨信网客服组:【微信客服】

    自信AI创作助手
    关于本文
    本文标题:第6章子程序结构.ppt
    链接地址:https://www.zixin.com.cn/doc/14656265.html

    Copyright ©2010-2026   All Rights Reserved  宁波自信网络信息技术有限公司 版权所有   |  客服电话:0574-28810668    微信客服:咨信网客服    投诉电话:18658249818   

    违法和不良信息举报邮箱:help@zixin.com.cn    文档合作和网站合作邮箱:fuwu@zixin.com.cn    意见反馈和侵权处理邮箱:1219186828@qq.com   | 证照中心

    12321jubao.png12321网络举报中心 电话:010-12321  jubao.png中国互联网举报中心 电话:12377   gongan.png浙公网安备33021202000488号  icp.png浙ICP备2021020529号-1 浙B2-20240490   


    关注我们 :微信公众号  抖音  微博  LOFTER               

    自信网络  |  ZixinNetwork