《汇编语言第5章王爽版(子程序调用指令).ppt》由会员分享,可在线阅读,更多相关《汇编语言第5章王爽版(子程序调用指令).ppt(24页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第5章结构化程序设计章结构化程序设计5.1 子程序的概念子程序的概念5.2 子程序的定义、调用和返回子程序的定义、调用和返回*5.3 子程序的现场保护与参数传递子程序的现场保护与参数传递*5.4 子程序子程序设计设计*5.5 子程序子程序的嵌套与递归调用的嵌套与递归调用5.6 宏汇编程序设计宏汇编程序设计教学基本内容教学基本内容5.1 子程序的概念子程序的概念1、子子程程序序:在在程程序序设设计计中中,我我们们会会发发现现一一些些多多次次无无规规律律重重复复的的程程序序段段或或语语句句序序列列。解解决决此此类类问问题题一一个个行行之之有有效效的的方方法法就就是是将将它它们们设设计计成成可可供
2、供反反复复调调用用的的独独立立的的子子程程序序结结构构,以以便便在在需需要要时时调用。在汇编语言中,子程序又称调用。在汇编语言中,子程序又称过程过程。过程(过程(子程序子程序):):是指是指功能相对独立的功能相对独立的一段程序。一段程序。主程序和子程序间的关系:主程序和子程序间的关系:调用子程序的程序称为调用子程序的程序称为主调程序或主调程序或主程序主程序,被调用的程序称为,被调用的程序称为子程序。子程序。、程序中使用子程序的好处、程序中使用子程序的好处子程序作为一个功能性模块,供一个程序甚至多个程序使用子程序作为一个功能性模块,供一个程序甚至多个程序使用:可以简化源程序结构可以简化源程序结构
3、;提高程序的可读性与可维护性提高程序的可读性与可维护性;有利于代码复用有利于代码复用;提高程序的设计效率。提高程序的设计效率。1 1、子子程程序序的的定定义义:由由子子程程序序定定义义伪伪指指令令PROCPROC和和ENDPENDP来来完完成成。其其格式如下:格式如下:子程序名子程序名 PROC NEAR/FARPROC NEAR/FAR ;过程体过程体子程序名子程序名 ENDPENDP解解释释:(1 1)子子程程序序名名是是子子程程序序入入口口地地址址的的符符号号表表示示。同同标标号号一一样,具有样,具有三种属性三种属性,即段属性、偏移地址属性以及类型属性。,即段属性、偏移地址属性以及类型属
4、性。(2 2)PROCPROC表示子程序定义开始,表示子程序定义开始,ENDPENDP表示子程序定义结束。表示子程序定义结束。(3)(3)NEAR/FARNEAR/FAR2 2、子程序的调用、子程序的调用和返回和返回过程定义后,可在主程序中用过程定义后,可在主程序中用CALLCALL指令,反复调用。指令,反复调用。过程结束,由返回指令过程结束,由返回指令RETRET返回主程序。返回主程序。演示演示演示演示5.2 子程序子程序的定义、调用和返回的定义、调用和返回子程序调用指令子程序调用指令(CALL)CALL指令分成指令分成4种类型种类型CALL子程序子程序名名 ;段内直接调用段内直接调用CAL
5、L r16/m16 ;段内间接调用段内间接调用CALL far ptr子程序子程序 ;段间直接调用段间直接调用CALL far ptr mem ;段间间接调用段间间接调用CALL指令需要保存返回地址:指令需要保存返回地址:段内调用段内调用偏移地址偏移地址IP入栈入栈SPSP2,SS:SPIP段间调用段间调用偏移地址偏移地址IP和段地址和段地址CS入栈入栈SPSP2,SS:SPCSSPSP2,SS:SPIP5.2 子程序子程序的定义、调用和返回的定义、调用和返回(续)(续)子程序返回指令子程序返回指令(RET)RETn功能:弹出功能:弹出CALL指令压入堆栈的返回地址指令压入堆栈的返回地址段内返
6、回段内返回偏移地址偏移地址IP出栈出栈 IPSS:SP,SPSP2段间返回段间返回偏移地址偏移地址IP和段地址和段地址CS出栈出栈IPSS:SP,SPSP2CSSS:SP,SPSP2注意:在使用注意:在使用CALL和和RET时,要保证过程的正确调用和返回时,要保证过程的正确调用和返回说明:说明:RET可以带参数可以带参数子程序返回指令子程序返回指令(RET)放在子程序的末尾,它使子程序在执行完任务后将堆栈中的放在子程序的末尾,它使子程序在执行完任务后将堆栈中的断点弹出,控制程序返回主程序继续执行被打断的程序。而断点弹出,控制程序返回主程序继续执行被打断的程序。而返回地址(断点)就是子程序调用时
7、入栈保护的断点地址返回地址(断点)就是子程序调用时入栈保护的断点地址IPIP(段内调用)或(段内调用)或IPIP和和CSCS值(段间调用)。通常,值(段间调用)。通常,RETRET指令的指令的类型是隐含类型是隐含的,它自动与子程序定义时的类型相匹配,如果的,它自动与子程序定义时的类型相匹配,如果是段内,返回时将栈顶的一个字弹给是段内,返回时将栈顶的一个字弹给IPIP寄存器;如为段间,寄存器;如为段间,返回时先从栈顶弹出一个字给返回时先从栈顶弹出一个字给IPIP,接着再弹出一个字给,接着再弹出一个字给CSCS。但是,当采用间接调用时,必须注意:保证但是,当采用间接调用时,必须注意:保证CALLC
8、ALL指令的类型指令的类型与过程中与过程中RETRET指令的类型匹配,以免发生错误。例如指令的类型匹配,以免发生错误。例如CALL CALL WORD PTRBXWORD PTRBX只能是段内调用,而只能是段内调用,而CALL DWORD PTRBXCALL DWORD PTRBX能够能够调用一个远过程(段间调用),这样调用一个远过程(段间调用),这样RETRET才能够识别返回类型。才能够识别返回类型。例:例:NEAR NEAR 类型子程序类型子程序 code SEGMENT ;code段段 CALL subp ;调用指令调用指令,xor指令的地址入指令的地址入栈栈 xor ax,ax mov
9、 ah,4ch int 21h subpsubp PROC NEAR ;子程序定义子程序定义 RET ;返回返回 subpsubp ENDP code ENDS END START、子程序的书写形式、子程序的书写形式1多多处处调调用用完完成成同同一一功功能能的的子子程序:程序:code SEGMENTstart:CALL sub CALL sub MOV AH,4CH INT 21Hsub PROC 、RETsub ENDPcode ENDS end start2模块化程序设计:多个子程序的调用模块化程序设计:多个子程序的调用code SEGMENTbegin:CALL sub1 CALL s
10、ub2 CALL sub3 MOV AH,4CH INT 21Hsub1 PROC 、RETsub1 ENDPsub2 PROC 、RETsub2 ENDPsub3 PROC 、RETsub3 ENDPcode ENDS END begin 子程序结构示例子程序结构示例子子程程序序的的位位置置通通常常在在主主程程序序的的所所有有可可执执行行指指令令之之前前或或之之后后,不不能能放放在在主主程程序序的的可可执执行行指指令令序序列列内内部部,否否则则会会破破坏主程序结构坏主程序结构5.3子程序的现场保护与参数传递子程序的现场保护与参数传递PROGPROCPUSH AXPUSH BX PUSH CX
11、;保护现场保护现场PUSH DX POPDXPOPCXPOPBX;恢复现场恢复现场POPAXRET ;返回断点处返回断点处PROGENDP例如:若子程序例如:若子程序PROG中中改变了寄存器改变了寄存器AX,BX,CX,DX的值,则可采用的值,则可采用此方法保护和恢复现场。此方法保护和恢复现场。一、一、信息的保护与恢复信息的保护与恢复二、二、主程序与过程的参数传递方式主程序与过程的参数传递方式主程序子程序的主程序子程序的参数参数传递:传递:l入口参数入口参数 也称入口条件,是指主程序调用子程序也称入口条件,是指主程序调用子程序前,为子程序内部数据处理准备所需的预置值;前,为子程序内部数据处理准
12、备所需的预置值;l出口参数出口参数 也称出口条件,是子程序返回主程序后也称出口条件,是子程序返回主程序后,把子程序处理的结果传递给主程序的数据。把子程序处理的结果传递给主程序的数据。参数传递的基本方法有:参数传递的基本方法有:(1 1)寄存器寄存器法法:通过通过CPUCPU寄存器传递参数。传递数据方便、快寄存器传递参数。传递数据方便、快捷,但所能传递的数据长度和个数都有限。捷,但所能传递的数据长度和个数都有限。(2 2)变变量量法法:通通过过内内存存单单元元(组组)传传递递参参数数。传传递递数数据据的的长长度度和个数可不受限制,程序设计比较灵活。和个数可不受限制,程序设计比较灵活。(3 3)堆
13、堆栈栈法法:通通过过堆堆栈栈传传递递参参数数。用用堆堆栈栈保保存存所所要要传传递递的的数数据据或或存存储储地地址址,利利用用堆堆栈栈数数据据存存取取的的特特点点,是是常常用用的的参参数数传传递方法。递方法。例例5-1:分别用三种参数传递方法编写求:分别用三种参数传递方法编写求12的和的程的和的程序。要求将结果送到内存单元,并显示。序。要求将结果送到内存单元,并显示。DATA SEGMENTSUM DB 0DATA ENDSSTACK SEGMENT DB 100 DUP(?)STACK ENDSCODE SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE START
14、:MOV AX,DATA MOV DS,AX MOV AL,1 MOV BL,2 CALL subprog mov ah,4cH int 21hCODE ENDS END STARTSubprog PROC ADD AL,BL OR AL,30H MOV SUM,AL Mov dl,al Mov ah,2 Int 21h RETsub ENDPF通过寄存器传送通过寄存器传送F通过变量传送通过变量传送DATA SEGMENTSUM DB 0 D1 DB?D2 DB?DATA ENDSSTACK SEGMENT DB 100 DUP(?)STACK ENDSCODE SEGMENT ASSUME
15、DS:DATA,SS:STACK,CS:CODESTART:MOV AX,DATA MOV DS,AX MOV D1,1 MOV D2,2 CALL SPROG MOV AH,4ch INT 21HCODE ENDS END STARTSPROG PROC MOV AL,D1 ADD AL,D2 OR AL,30H MOV SUM,AL MOV dl,al MOV ah,2 INT 21h RETSPROG ENDPEND STARTSprPROCPUSH BPMOV BP,SPMOV AX,BP+6MOV BX,BP+4ADD AL,BL OR AL,30HMOV DL,AL MOV AH,
16、2 INT 21H MOV SUM,ALPOP BPRETSpr ENDPDATA SEGMENTSUM DB 0DATA ENDSSTACK SEGMENT DB 100 DUP(?)STACK ENDSCODE SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE START:MOV AX,DATA MOV DS,AX MOV AL,1 MOV BL,2 MOV AH,0 MOV BH,0 PUSH AX PUSH BX CALL SPR POP BX POP AX MOV AH,4CH INT 21HCODE ENDSEND STARTF通过堆栈通过堆栈功能最强
17、功能最强/最灵活最灵活/最复最复杂杂例例5-2:多字节数相加的程序(寄存器传递过程参数):多字节数相加的程序(寄存器传递过程参数)data segmentnum1 db 01h,02h,03h,04h,05h,06hnum2 db 0ffh,07h,0ffh,03h,01h,06hlen equ$-num2data endsstack segment stack dw 100 dup(?)stack endscode segment assume cs:code,ds:data,ss:stackStart:mov ax,data mov ds,ax lea si,num1 lea di,num
18、2 mov cx,len call mpadd mov ah,4ch int 21hMpadd proc push ax push cx push si push di jcxz exit clcNext:mov al,di adc si,al inc si inc di loop nextExit:pop di pop si pop cx pop ax retMpadd endpCode ends end start例例5-3多字数相加的程序(堆栈传递子程序参数多字数相加的程序(堆栈传递子程序参数)RET指令中参数的应用例子指令中参数的应用例子data segmentva11 dw 9898
19、h,7676h,5454h,3232h ;被加数;被加数va12 dw 9898h,7676h,5454h,3232h ;加数;加数buffer dw 4 dup(?);和;和len equ$-bufferdata endsstack segment stack dw 100 dup(?)stack endscode segment assume cs:code,ds:data,ss:stack,es:data;主程序为过程;主程序为过程MAIN PROC FAR push ds xor ax,ax push ax mov ax,data mov ds,ax mov es,ax mov ax,
20、len/2 push ax mov ax,offset buffer push ax mov ax,offset va11 push ax mov ax,offset va12 push axCall add64 mov ah,4ch int 21hmain endp;主程序结束;主程序结束;子过程ADD64开始add64 proc push bp ;mov bp,sp push bx push si push di push cx pushf ;保存现场 mov si,bp+4;mov bx,bp+6 mov di,bp+8 mov cx,bp+10 ;读取参数 cld clcagain:l
21、odsw adc ax,bx stosw inc bx inc bx loop again popf ;pop cx pop di pop si pop bx pop bp ;恢复现场 ret 8 ;返回调用点,并废除4个参数共8字节add64 endp ;子过程结束code ends end main 在子程序设计中在子程序设计中 要要明明确确地地定定义义出出这这个个子子程程序序的的入入口口参参数数和和出出口口参参数数,使使调调用用者能方便地使用子程序。者能方便地使用子程序。在在子子程程序序中中要要合合理理地地保保存存主主程程序序和和子子程程序序都都用用到到的的寄寄存存器器和和存储单元存储单
22、元,以使主程序能正确地运行。,以使主程序能正确地运行。子程序是提高程序设计效率的良好手段,也为模块化设计提供子程序是提高程序设计效率的良好手段,也为模块化设计提供了很好的基础。了很好的基础。总结总结总结总结注意:前面所介绍的三种传递参数的方法,并不是固定不变的。注意:前面所介绍的三种传递参数的方法,并不是固定不变的。即它们是可以综合使用的。要按照实现的需要和具体情况的不即它们是可以综合使用的。要按照实现的需要和具体情况的不同,可以使用其中一种方式,也可以同时使用几种混合的方式,同,可以使用其中一种方式,也可以同时使用几种混合的方式,有的时候还可能并不需要参数的传递。有的时候还可能并不需要参数的传递。总之,调用程序和子程序之间的参数传递,的确十分重要,总之,调用程序和子程序之间的参数传递,的确十分重要,参数不宜使用太多。参数选择的适当,可以简化程序设计。参数不宜使用太多。参数选择的适当,可以简化程序设计。参数确定之后,就是如何进行传递的问题。无论采用哪一参数确定之后,就是如何进行传递的问题。无论采用哪一种传递方式,都应该保证正确无误的传递。这是调用程序和子种传递方式,都应该保证正确无误的传递。这是调用程序和子程序的协调关系。这也是在子程序设计中需要认真解决的问题。程序的协调关系。这也是在子程序设计中需要认真解决的问题。