




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第4章 程序设计方法第4章 子程序设计子程序设计 本章着重讲述本章着重讲述6个方面的内容:个方面的内容:(1)如何通过伪指令如何通过伪指令PROC-ENDP在汇编源程在汇编源程序中定义一个子程序。序中定义一个子程序。(2)CALL调用指令的调用指令的4种使用形式和返回地址种使用形式和返回地址的保存。的保存。(3)RET返回指令的返回指令的4种使用形式。种使用形式。(4)在子程序中进行现场保护和现场恢复。在子程序中进行现场保护和现场恢复。(5)调用程序与子程序问的调用程序与子程序问的3种参数传递方法。种参数传递方法。(6)利用利用DOS提供的系统功能调用,实现数据提供的系统功能调用,实现数据的输
2、入与输出。的输入与输出。开开 始始第4章 程序设计方法4.1子程序的定义和格式及设计步骤子程序的定义和格式及设计步骤 4.1.1 子程序的定义和格式子程序的定义和格式4.1.2 子程序的设计步骤和子程序的说明文件子程序的设计步骤和子程序的说明文件返回本章首页返回本章首页第4章 程序设计方法4.1.1 子程序的定义和格式子程序的定义和格式在汇编语言中,要使某一程序段成为一个子程序,必须在汇编语言中,要使某一程序段成为一个子程序,必须首先通过过程定义伪指令首先通过过程定义伪指令PROC和和ENDP来把它定义成为一个子程序。来把它定义成为一个子程序。过程定义格式:过程定义格式: PROC NEAR/
3、FAR;NEAR表示过程在本表示过程在本代码段内,代码段内,FAR表示过程在其他代码段内,表示过程在其他代码段内, ; RET ;返回指令;返回指令 ENDP子程序可以采用子程序可以采用CALL指令来调用。调用一个过程的格指令来调用。调用一个过程的格式为:式为:CALL 过程名过程名返回本节返回本节第4章 程序设计方法其中其中与标号类似,具有与标号类似,具有3种属性种属性(偏移、段和类偏移、段和类型型),它也是所定义子程序入,它也是所定义子程序入口的符号地址。类型属性中的口的符号地址。类型属性中的NEAR和和FAR指明该段的指明该段的调用范围。调用范围。NEAR表示段内调用,即指调用程序表示段
4、内调用,即指调用程序(主主程序程序)和子程序在同一个代码段中。如果一个子程序和子程序在同一个代码段中。如果一个子程序定义为是段内调用的,那么在定义中可以省略定义为是段内调用的,那么在定义中可以省略NEAR不写。不写。FAR表示段间调用,即指调用程序和子程序表示段间调用,即指调用程序和子程序分别在两个不同的代码段中。如果一个子程序定义分别在两个不同的代码段中。如果一个子程序定义为是段间调用的,那么在定义中不能省略为是段间调用的,那么在定义中不能省略FAR。 第4章 程序设计方法4.1.2 子程序的设计步骤和子程序的说明文件子程序的设计步骤和子程序的说明文件汇编语言程序设计一般有以下几个步骤:汇编
5、语言程序设计一般有以下几个步骤:1确定子程序的名称和调用类型。确定子程序的名称和调用类型。2确定子程序完成的功能。确定子程序完成的功能。3确定子程序运行时所需的入口参数,以及主程序与确定子程序运行时所需的入口参数,以及主程序与子程序之间的入口参数传递方式。子程序之间的入口参数传递方式。4确定子程序返回时,将运算结果(即出口参数)以确定子程序返回时,将运算结果(即出口参数)以什么方式提交给主程序。什么方式提交给主程序。5确定子程序运行时使用寄存器和内存单元的情况,确定子程序运行时使用寄存器和内存单元的情况,并进行现场保护。并进行现场保护。6编写子程序的说明文件。编写子程序的说明文件。第4章 程序
6、设计方法【例【例4-1】子程序的说明文件示例】子程序的说明文件示例 后面将要讲到的【例后面将要讲到的【例4-11】中子程序的说明文件】中子程序的说明文件1子程序名:子程序名:BCD-16B;2子程序完成的功能:将一组分离子程序完成的功能:将一组分离BCD数转换成数转换成16位二进位二进制数;制数;3子程序的入口参数:待转换的分离子程序的入口参数:待转换的分离BCD数在内存中的首数在内存中的首地址,在地址,在ES:SI,BCD数的字节数存放在寄存器数的字节数存放在寄存器CX中;中;4子程序的出口参数:转换成的子程序的出口参数:转换成的16位二进制数,在位二进制数,在DX中:中:5子程序用到的寄存
7、器:子程序用到的寄存器:CX,DX,ES,SI;6典型例子。典型例子。第4章 程序设计方法返回本节返回本节若内存中的若内存中的BCD数定义为:数定义为:BCD DB 00H,04H,00H,01H,00H;即;即BCD数是数是01040D0000010000010000B当当(ES) = BCD的段地址,的段地址,(ST)= BCD的偏移地址,的偏移地址,(CX)=5结果结果(DX) = 0000010000010000B本子程序中虽还用到了寄存器本子程序中虽还用到了寄存器AX和和BX,但由于在子程序中已将相,但由于在子程序中已将相应内容保护入栈,所以,从调用程序来看,子程序对这两个寄应内容保
8、护入栈,所以,从调用程序来看,子程序对这两个寄存器的内容没有影响。存器的内容没有影响。第4章 程序设计方法4.2 子程序的调用和返回子程序的调用和返回主程序中是通过使用主程序中是通过使用CALL指令来实现对子程序的调用的。指令来实现对子程序的调用的。而子程序执行完毕后返回而子程序执行完毕后返回到主程序,则是通过子程序中的到主程序,则是通过子程序中的RET指令来完成的。当执指令来完成的。当执行中遇到行中遇到CALL 指令时,就转移到名为指令时,就转移到名为的子程序去执的子程序去执行,当子程序执行到指令行,当子程序执行到指令RET时,就返回主程序的指令时,就返回主程序的指令CALL 的下一条指令的
9、下一条指令(一般都称其为断点一般都称其为断点);接着,又回到主程序里;接着,又回到主程序里执行。执行。 返回本章首页返回本章首页第4章 程序设计方法调用子程序有时也称为调用子程序有时也称为“转子转子”,即,即“转移到转移到子程序入口处执行子程序入口处执行”的意思。当要转去执的意思。当要转去执行的子程序定义为段内调用时,为了转移到子行的子程序定义为段内调用时,为了转移到子程序入口处,只需修改程序入口处,只需修改IP寄存器的内容即可。寄存器的内容即可。当要转去执行的子程序定义为段间调用时,当要转去执行的子程序定义为段间调用时,意味着意味着“调用调用”要转移到另一个段去执行,要转移到另一个段去执行,
10、这时的子程序入口地址转移到新的段地址和这时的子程序入口地址转移到新的段地址和偏移地址,此时不仅要修改寄存器偏移地址,此时不仅要修改寄存器IP的内容,的内容,还要修改寄存器还要修改寄存器CS的内容。的内容。第4章 程序设计方法4.2.1调用与返回指令调用与返回指令1. 调用指令调用指令CALL程序程序“调用调用”,意味着程序的执行离开了,意味着程序的执行离开了“原来的地方原来的地方”,形成,形成“断断点点”,转去执行子程,转去执行子程序。子程序执行完毕后,又要回到序。子程序执行完毕后,又要回到“断点断点”,继续执行原来的程序。,继续执行原来的程序。为此,必须先做好返回地址的保存,即调用程序现场的
11、保护工作,为此,必须先做好返回地址的保存,即调用程序现场的保护工作,以便调用程序现场的恢复。所以,调用指令的基本功能的第一步,以便调用程序现场的恢复。所以,调用指令的基本功能的第一步,是将返回地址(也称断点地址),即调用指令的下一条指令的地是将返回地址(也称断点地址),即调用指令的下一条指令的地址压入堆栈。并按照某种寻址方式转向子程序的入口。子程序执址压入堆栈。并按照某种寻址方式转向子程序的入口。子程序执行完毕后,再从堆栈中弹出返回地址。因此,必须牢记堆栈操作行完毕后,再从堆栈中弹出返回地址。因此,必须牢记堆栈操作“先进后出先进后出”的原则,以免失误。的原则,以免失误。子程序入口地址的寻址方式
12、与无条件转移指令的寻址方式基本相同。子程序入口地址的寻址方式与无条件转移指令的寻址方式基本相同。调用指令同样可以调用指令同样可以分为段内调用与段间调用:段内调用又分为相对寻址和间接寻址;段分为段内调用与段间调用:段内调用又分为相对寻址和间接寻址;段间调用则又分为直接寻址与间接寻址两种寻址方式。间调用则又分为直接寻址与间接寻址两种寻址方式。第4章 程序设计方法为了实现主程序调用子程序以及子程序自动返回主程序。几乎所有指为了实现主程序调用子程序以及子程序自动返回主程序。几乎所有指令系统都提供一组令系统都提供一组调用和返回指令。关于调用和返回指令。关于80868088指令系统中的调用与返回指令的助指
13、令系统中的调用与返回指令的助记符格式以及指令基本功能的讨论如下:记符格式以及指令基本功能的讨论如下:段内调用的相对寻址方式段内调用的相对寻址方式对于段内调用指令,相对寻址方式的位移量只有对于段内调用指令,相对寻址方式的位移量只有16位一种,也就是它位一种,也就是它没有短调用。其没有短调用。其指令形式为指令形式为 CALL 该指令的功能是:先将当前调用指令的下一条指令的地址(该指令的功能是:先将当前调用指令的下一条指令的地址(16位)压位)压入堆栈,并修改堆栈指针:入堆栈,并修改堆栈指针:(SP)(SP)2,(SP)+1:(SP)(IP)再将当前的再将当前的“下一条指令的地址下一条指令的地址”加
14、上加上“子程序的入口地址子程序的入口地址”的的16位位的偏移量:的偏移量:(IP)D16此时,子程序和主程序在同一个代码段内。此时,子程序和主程序在同一个代码段内。第4章 程序设计方法【例【例4-2】设】设SUB为一个为一个,其属性为,其属性为NEAR类型。则类型。则下面的指令下面的指令CALL SUB 或或 CALL SUB NEAR是段内调用的相对寻址方式是段内调用的相对寻址方式段内调用的间接寻址方式段内调用的间接寻址方式其指令形式为其指令形式为CALL 该指令的功能是:先将当前调用指令的下一条指令的地址(该指令的功能是:先将当前调用指令的下一条指令的地址(16位)压入位)压入堆栈,并修改
15、堆栈指针:堆栈,并修改堆栈指针:(SP)(SP)2,(SP)+1:(SP)(IP)再将当前的再将当前的“下一条指令的地址下一条指令的地址” 修改为修改为“子程序的入口地址子程序的入口地址”,用偏,用偏移量移量EA表示:表示:(IP)EA此时,子程序和主程序仍在同一个代码段内。这里的此时,子程序和主程序仍在同一个代码段内。这里的EA可以是基址寄存可以是基址寄存器器BX或变址寄存器或变址寄存器SI和和DI的内容,也可以是各种寻址方式的存储器操的内容,也可以是各种寻址方式的存储器操作数。作数。第4章 程序设计方法【例【例4-3】段内间接调用的各种寻址方式】段内间接调用的各种寻址方式CALL BX ;
16、偏移地址在寄存器;偏移地址在寄存器BX之中之中CALL SI ;偏移地址在存储器中,;偏移地址在存储器中,EASI,PA(DS)10H(SI)设设VARW为一个为一个,其属性为,其属性为NEAR类型。类型。CALL VARW ;偏移地址在已定义的变量;偏移地址在已定义的变量VARW字单字单元中,段内调用只有字元中,段内调用只有字操作一种格式,所以属性操作符操作一种格式,所以属性操作符WORD PTR可以省略。可以省略。CALL VARWDI ;偏移地址在;偏移地址在VARWDI字单元中。字单元中。第4章 程序设计方法段间调用的直接寻址方式段间调用的直接寻址方式其指令形式为其指令形式为CALL
17、FAR PTR 该指令的功能是:先将当前调用指令的下一条指令的地址,包括该指令的功能是:先将当前调用指令的下一条指令的地址,包括代码段地址和偏移地址先后压入堆栈,并修改堆栈指针:代码段地址和偏移地址先后压入堆栈,并修改堆栈指针:(SP)(SP)2,(SP)+1:(SP)(CS)(SP)(SP)2,(SP)+l:(SP)(IP)再将当前的再将当前的“下一条指令的地址下一条指令的地址”,修改为子程序的入口的另一,修改为子程序的入口的另一代码段地址和相应的偏移地址:代码段地址和相应的偏移地址:(IP)的偏移地址的偏移地址(CS)的段地址的段地址此时,子程序和主程序不在同一个代码段内。此时,子程序和主
18、程序不在同一个代码段内。第4章 程序设计方法【例【例4-4】设】设SUB2为一个为一个,其属性为,其属性为FAR类型。则类型。则下面的指令下面的指令CALL SUB2 或或 CALL FAR PTR SUB2 是段间调用的直接寻址方式是段间调用的直接寻址方式段间调用的间接寻址方式段间调用的间接寻址方式其指令形式为其指令形式为 CALL 该指令的功能是:先将当前调用指令的下一条指令的地址,包括代码段该指令的功能是:先将当前调用指令的下一条指令的地址,包括代码段地址和偏移地址先后压入堆栈,并修改堆栈指针:地址和偏移地址先后压入堆栈,并修改堆栈指针:(SP)(SP)2,(SP)+1:(SP)(CS)
19、(SP)(SP)2,(SP)+l:(SP)(IP)再将当前的再将当前的“下一条指令的地址下一条指令的地址”,修改为子程序的入口的另一代码段,修改为子程序的入口的另一代码段地址和相应的偏移地址:地址和相应的偏移地址:(IP)以以EA形式给出的形式给出的 的偏移地址的偏移地址(CS)以以EA形式给出的形式给出的的所在的段地址的所在的段地址这里的这里的EA可以是基址寄存器可以是基址寄存器BX或变址寄存器或变址寄存器SI和和DI的内容,也可以是的内容,也可以是各种寻址方式的存储器操作数。各种寻址方式的存储器操作数。第4章 程序设计方法【例【例4-5】段间间接调用的各种寻址方式】段间间接调用的各种寻址方
20、式CALL VAR32 ;EA=VAR32,VAR32是是双字变量双字变量 CALL DWORD PTR BX ;EA=BX CALL DWORD PTR TABLEBX SI ;EA= TABLE +BXSI都是段间调用的间接寻址方式都是段间调用的间接寻址方式第4章 程序设计方法2 返回指令返回指令RET 子程序在其任务完成后,执行的最后一条汇编指令子程序在其任务完成后,执行的最后一条汇编指令是是RET,根据对该子程序的调用是段内调用还是段,根据对该子程序的调用是段内调用还是段间调用,其要实现的操作是不相同的。如果是段内间调用,其要实现的操作是不相同的。如果是段内调用,那么调用,那么RET指
21、令的功能只是把存放在堆栈里的指令的功能只是把存放在堆栈里的返回地址送返回地址送IP寄存器;如果是段间调用,那么寄存器;如果是段间调用,那么RET指令的功能就是要把存放在堆栈里的返回地址和段指令的功能就是要把存放在堆栈里的返回地址和段地址,分别送地址,分别送IP寄存器和寄存器和CS寄存器。因此,寄存器。因此,RET指指令的使用也有多种形式:段内返回、段内带立即数令的使用也有多种形式:段内返回、段内带立即数返回、段间返回和段间带立即数返回。下面对它们返回、段间返回和段间带立即数返回。下面对它们一一加以介绍。一一加以介绍。第4章 程序设计方法段内返回段内返回格式:格式:RET执行的操作:执行的操作:
22、IP(SP+1)(SP),SPSP2即将当前栈项元素内容即将当前栈项元素内容(就是断点的地址就是断点的地址)送寄存器送寄存器IP,然后往栈底,然后往栈底方向调整堆栈指针,达方向调整堆栈指针,达到栈顶元素出栈的目的。到栈顶元素出栈的目的。段内带立即数返回段内带立即数返回格式:格式:RET n (或或 RET )立即数,立即数,n通常是正偶数。如果汇编格式指令中的通常是正偶数。如果汇编格式指令中的n或表达式计算或表达式计算出的值是奇数,汇出的值是奇数,汇编时会自动变成编时会自动变成n + l。执行的操作:执行的操作:IP(SP+1)(SP),SPSP+2,SPSP + n第4章 程序设计方法段间返
23、回段间返回格式:格式:RET执行的操作:执行的操作: IP(SP+1)(SP),SPSP+2;CS(SP+1)(SP),SPSP+2段间带立即数返回段间带立即数返回格式:格式:RET n执行的操作:执行的操作:IP(SP+1)(SP),SPSP+2;CS(SP+1)(SP),SPSP+2,SPSP + n第4章 程序设计方法段内返回和段间返回指令的汇编指令格式都是段内返回和段间返回指令的汇编指令格式都是RET,但,但是汇编后产生的机器代码指令却是不同的。当子程是汇编后产生的机器代码指令却是不同的。当子程序的属性是序的属性是NEAR时,对应于段内返回时,对应于段内返回RET指令的指令的机器代码是
24、机器代码是C3H,对应于段内带立即数返回,对应于段内带立即数返回REI指令指令的机器代码是的机器代码是C2H;当子程序的属性是;当子程序的属性是FAR时,对时,对应于段间返回应于段间返回RET指令的机器代码是指令的机器代码是CBH,对应于,对应于段间带立即数返回段间带立即数返回RET指令的机器代码是指令的机器代码是CAH。所。所以,我们强调定义一个子程序为段间调用时,其类以,我们强调定义一个子程序为段间调用时,其类型属性型属性FAR是绝对不能省略的,否则就不能正确实是绝对不能省略的,否则就不能正确实现返回。属性是现返回。属性是FAR的子程序也可以被同一代码段的子程序也可以被同一代码段的主程序调
25、用。这时,的主程序调用。这时,CALL指令虽然与子程序同在指令虽然与子程序同在一个代码段中,但它执行的却是段间调用操作。由一个代码段中,但它执行的却是段间调用操作。由此也表明,此也表明,CALL指令的属性是由过程的属性决定的。指令的属性是由过程的属性决定的。第4章 程序设计方法【例【例4-6】段间调用的程序描述】段间调用的程序描述DATA SEGMENT。VARD DD SUBP ;定义一个双字变量;定义一个双字变量VARD,它的数据是子程序,它的数据是子程序SUBP的第一的第一条指令的第一个字节的内存地址,其偏移地址存入低地址,条指令的第一个字节的内存地址,其偏移地址存入低地址,段地址存入高
26、地址。实际上就是定义子程序段地址存入高地址。实际上就是定义子程序VARD,它就是,它就是子程序子程序SUBP DATA ENDSCODE 1 SEGMENTCALL SUBP ;子程序;子程序SUBP在另一个代码段在另一个代码段CODE2,所以是段间直接,所以是段间直接调用调用CALL VARD ;实际上是段间间接调用;实际上是段间间接调用SUBP,因,因VARD已定义为双字变已定义为双字变量量第4章 程序设计方法LEA SI,VARD ;送双字变量;送双字变量VARD的偏移地址到寄存器的偏移地址到寄存器SICALL DWORD PTRSI;段间间接调用,;段间间接调用,DWORD PTR不能
27、省不能省略,表明取略,表明取32位数据位数据CODE l ENDSCODE2 SEGMENI SUBP PROC FAR;定义名为;定义名为SUBP的子程序,的子程序,FAR属性不可省属性不可省略略 RET;子程序返回指令;子程序返回指令SUBP ENDPCODE2 ENDS第4章 程序设计方法4.2.2 现场的保护与恢复现场的保护与恢复 前面说过,在子程序调用的操作中,必须做好调用程序现场的保护前面说过,在子程序调用的操作中,必须做好调用程序现场的保护工作,以便调用程序现场的恢复。工作,以便调用程序现场的恢复。保护与恢复现场的工作可以在主程序中完成,也可以在子程序中完保护与恢复现场的工作可以
28、在主程序中完成,也可以在子程序中完成。一般情况下,是在子程序的开始安排一串保护现场的语句。成。一般情况下,是在子程序的开始安排一串保护现场的语句。在子程序的返回指令之前再恢复现场。这样处理,主程序在转子在子程序的返回指令之前再恢复现场。这样处理,主程序在转子前后均不必考虑保护、恢复现场的工作,其处理流程显得清晰。前后均不必考虑保护、恢复现场的工作,其处理流程显得清晰。尤其是当多处调用同一子程序时,每处都省去了转子前后保存与尤其是当多处调用同一子程序时,每处都省去了转子前后保存与恢复现场的语句串。这些工作集中在子程序中去做,整个代码简恢复现场的语句串。这些工作集中在子程序中去做,整个代码简短而紧
29、凑。短而紧凑。通过子程序的调用和返回指令的学习,可以知道,在子程序中用到通过子程序的调用和返回指令的学习,可以知道,在子程序中用到某些寄存器某些寄存器(或存储单元或存储单元),就可能破坏这些寄存器,就可能破坏这些寄存器(或存储单元或存储单元)在转子程序前原有的内容。因此,若子程序在转子程序前原有的内容。因此,若子程序A中可能改变寄存器中可能改变寄存器AX、BX、CX、DI、SI五个寄存器的内容,则在子程序的开始处五个寄存器的内容,则在子程序的开始处应将这些寄存器的内容入栈保护,在子程序的返回指令之前用出应将这些寄存器的内容入栈保护,在子程序的返回指令之前用出栈指令逐个恢复。栈指令逐个恢复。第4
30、章 程序设计方法实现方法就是,把子程序或过程的定义格式扩充实现方法就是,把子程序或过程的定义格式扩充为如下的格式:为如下的格式: PROCPUSH AXPUSH BXPUSH CX 保护现场保护现场PUSH DIPUSH SI 子程序工作部分子程序工作部分POP SIPOP DI POP CX 恢复现场恢复现场POP BXPOP AXRET ;返回断点处;返回断点处 ENDP 第4章 程序设计方法注意,由于是在栈中保存各寄存器的内容,所注意,由于是在栈中保存各寄存器的内容,所以,要依后进先出的原则,从栈中弹出信息以,要依后进先出的原则,从栈中弹出信息送入相应的寄存器。上例中入栈保护的顺序送入相
31、应的寄存器。上例中入栈保护的顺序是是AX、BX、CX、DI、SI,出栈恢复的顺序,出栈恢复的顺序则相反,即则相反,即SI、DI、CX、BX、AX。这样才。这样才能保证子程序的运行不破坏主程序的工作现能保证子程序的运行不破坏主程序的工作现场。场。第4章 程序设计方法【例【例4-7】下面给出的是一个名为】下面给出的是一个名为SUBP的子程序的定义格式,考的子程序的定义格式,考虑到了现场的保护与虑到了现场的保护与恢复:恢复:SUBP PROC NEARPUSH AXPOP AXRETSUBP ENDP从定义中可以看出,它属于段内调用从定义中可以看出,它属于段内调用(NEAR),因此也可以把,因此也可
32、以把NEAR省略。省略。第4章 程序设计方法4.3主程序与子程序之间传递参数的方式主程序与子程序之间传递参数的方式 4.3.1 寄存器法寄存器法4.3.2 约定存储单元法约定存储单元法4.3.3堆栈传递参数法堆栈传递参数法返回本章首页返回本章首页第4章 程序设计方法4.3.1 寄存器法寄存器法寄存器法就是子程序的入口参数和出口参数都寄存器法就是子程序的入口参数和出口参数都在约定的寄存器之中。此法的优点是信息传在约定的寄存器之中。此法的优点是信息传递快编程也较方便且节省内存单元。但递快编程也较方便且节省内存单元。但由于寄存器的个数是有限的,而且在处理过由于寄存器的个数是有限的,而且在处理过程中要
33、经常使用寄存器,如果要传送的参数程中要经常使用寄存器,如果要传送的参数很多,将导致无空闲寄存器供编写程序使很多,将导致无空闲寄存器供编写程序使用所以,寄存器法只适用于要传递的参数用所以,寄存器法只适用于要传递的参数较少的情况。较少的情况。第4章 程序设计方法【例【例4-8】编程计算】编程计算3个个16位无符号整数的平方根之和位无符号整数的平方根之和分析问题:本题采用连续减奇数法求平方根的算法:将整数依次分析问题:本题采用连续减奇数法求平方根的算法:将整数依次减去奇数减去奇数1,3,5,7,(2n1)。所能执行这种减法的次数,即是所求数的平方根。所能执行这种减法的次数,即是所求数的平方根值。比如
34、,要求数值。比如,要求数25的平方根。那么依次做下面的减法:的平方根。那么依次做下面的减法:25l = 24 ;减第;减第1次次243 = 21 ;减第;减第2次次2l5 = 16 ;减第;减第3次次167 = 9 ;减第;减第4次次99 = 0 ;减第;减第5次次 这表明减法可以进行这表明减法可以进行5次,因此次,因此25的平方根是的平方根是5。下面,将这种求。下面,将这种求平方根的算法编写成名为平方根的算法编写成名为SQROT的子程序。的子程序。第4章 程序设计方法确定算法:本题要作两个循环:内循环求平方根,采用确定算法:本题要作两个循环:内循环求平方根,采用子程序。所以主程序向子程子程序
35、。所以主程序向子程序传递的参数是序传递的参数是3个被开方数,子程序向主程序传递的个被开方数,子程序向主程序传递的参数是参数是3个方根。外循环累加平方根个方根。外循环累加平方根之和,循环次数已知是之和,循环次数已知是3次,故用循环次数作为外循环次,故用循环次数作为外循环的控制条件,配合使用的控制条件,配合使用LOOP指令。指令。内循环因为要作连续减法,循环次数不定,所以用内循环因为要作连续减法,循环次数不定,所以用CF1,表示当减法需借位时,子循环结束。,表示当减法需借位时,子循环结束。子程序与主程序之间采用寄存器方式传递参数。即:主子程序与主程序之间采用寄存器方式传递参数。即:主程序把输入参数
36、放在程序把输入参数放在DX中,传递给子程序;子程序中,传递给子程序;子程序将输出参数放在将输出参数放在AX里,传递给主程序。注意现场保里,传递给主程序。注意现场保护。显然,不能对存放输出参数的护。显然,不能对存放输出参数的AX寄存器进行现寄存器进行现场保护,否则子程序的操作就白作了。场保护,否则子程序的操作就白作了。 第4章 程序设计方法画程序流程图:略。画程序流程图:略。确定汇编语言程序的基本框架:可见,该汇编语言程序确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:的基本框架至少要两个段:数据段和代码段。数据段中定义数据段和代码段。数据段中定义2个变量:一个数组变个变
37、量:一个数组变量量VARW,题设为,题设为16位数,应选位数,应选DW 类型,使用寄类型,使用寄存器存器SI定位。另一个是和数定位。另一个是和数SUM变量,也选变量,也选DW类型,类型,其中间结果放在寄存器其中间结果放在寄存器BX。平方根放在寄存器。平方根放在寄存器AX。还有一个数还有一个数N,为循环次数,计数器用,为循环次数,计数器用CX。编写程序,可以想得到,需要编写程序,可以想得到,需要MOV、SUB 、ADD 、LEA 、INC、CALL、JMP、JC、PUSH、POP和和LOOP等指令,最后要返回等指令,最后要返回DOS。未想到的,在编写过程中随时添加,如未想到的,在编写过程中随时添
38、加,如XOR指令等。指令等。第4章 程序设计方法具体程序如下:具体程序如下:DATA SEGMENT VARW DW 81,144,289SUM DW ?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART: MOV AX,DATA MOV DS,AX ;XOR BX,BX ;BX清清0,存放平方根之和,存放平方根之和LEA SI,VARW ;送数组变量;送数组变量VARW的起始偏移地址到寄存器的起始偏移地址到寄存器SIMOV CX,3LOP: LEA DX,SI ;输入参数,;输入参数,DX81,144,289CALL SQROT ;调用子程序;
39、调用子程序SQROTADD BX,AX ;累加平方根;累加平方根ADD SI,2 ;SI SI2,移到下一个数,移到下一个数LOOP LOP ;CX CX1,若,若CX0,循环到,循环到LOP语句,直到语句,直到CX0。MOV SUM,BX ;将最后结果送;将最后结果送SUM 内存单元内存单元 MOV AH,4CHINT 21H第4章 程序设计方法*以下为子程序以下为子程序*SQROT PROCPUSH CX :现场保护:现场保护PUSH DX ;现场保护;现场保护MOV CX,1 ;奇数初值为;奇数初值为1XOR AX,AX;AX清清0,存放平方根值,存放平方根值SQRl: SUB DX,C
40、X ;循环减奇数,初始减;循环减奇数,初始减1JC SQR 2 ;若;若CF1,减法需借位,转移到,减法需借位,转移到SQR 2,结束循环的条件,结束循环的条件INC AX ;若;若CF1,够减,寄存器,够减,寄存器AX加加1,记录减法的次数,最,记录减法的次数,最后即得所求数的平方根值后即得所求数的平方根值ADD CX,2 ;奇数递增;奇数递增JMP SQR l ;跳到;跳到SQR l,循环作减法,循环作减法SOR2: POP DX :现场恢复:现场恢复POP CX ;现场恢复;现场恢复RET ;返回,输出参数在;返回,输出参数在AX*子程序结束子程序结束*SQROT ENDPCODE EN
41、DSEND START第4章 程序设计方法具体程序如下:具体程序如下:DATA SEGMENT DAT DB ,;定义数组变量,有数据;定义数组变量,有数据N1个个DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AX ;数据段初始化;数据段初始化MOV CX,N1 ;将外、内循环次数送寄存器;将外、内循环次数送寄存器CX保存保存LOPl: XOR SI,SI ;寄存器;寄存器SI清零,使外循环体每轮循环都从第一个开始清零,使外循环体每轮循环都从第一个开始PUSH CX ;保存外循环次数;保存外循环次数 第4章
42、 程序设计方法*内循环开始内循环开始*LOP2: MOV AL,DATSI ;取国名的第一个字母;取国名的第一个字母CMP AL,DATSI+3 ;比较相邻两个国名的第一个字母;比较相邻两个国名的第一个字母JLE LOP3 ;符合顺序,转移到;符合顺序,转移到LOP3语句语句CALL MPR 0 ;不符合顺序,则调用交换子程序;不符合顺序,则调用交换子程序MPR 0LOP3: ADD SI,3 ;SI SI3,指向下一个国名,指向下一个国名LOOP LOP2 ;CXCX1,若,若CX0,则循环到,则循环到LOP2,继续比,继续比较下一较下一对相邻两个国名的第一个字母,直到对相邻两个国名的第一个
43、字母,直到CX0为止,形成内为止,形成内循环控制循环控制*内循环结束内循环结束*第4章 程序设计方法INC SI ;SI SI1,指向国名的第二个字母,指向国名的第二个字母POP CX ;恢复外循环次数;恢复外循环次数LOOP LOP1 ;CXCX1,若,若CX0,则循环到,则循环到LOP1,继,继续对国名的第二个字母进行比较,直到续对国名的第二个字母进行比较,直到CX0为止,形成外循为止,形成外循环控制。再循环到环控制。再循环到LOP1,继续对国名的第三个字母进行比,继续对国名的第三个字母进行比较,较,MOV AH,4CHINT 2lH*子程序开始子程序开始*MPR 0 PROC ;实现交换
44、功能的子程序,入口参数;实现交换功能的子程序,入口参数SIPUSH CX ;现场的保护,(;现场的保护,(CS)压栈)压栈PUSH SI ;现场的保护,(;现场的保护,(IP)压栈)压栈第4章 程序设计方法MOV CX,3 ;CX3, MPR l: MOV AL,SI ;通过寄存器;通过寄存器AL向子程序传递入口参数,即将第一向子程序传递入口参数,即将第一个国名的第一个字母送寄存器个国名的第一个字母送寄存器AL XCHG AL,BYTE PTRSI+3 ;将(;将(AL)与相邻国名的第一个字母交换,)与相邻国名的第一个字母交换,MOV BYTE PTRSI,AL ;将(;将(AL)送内存单元)
45、送内存单元SI,实现将字母靠,实现将字母靠后的国名往后移,同时字母靠前的国名往后的国名往后移,同时字母靠前的国名往前移的操作,向主程序返回参数前移的操作,向主程序返回参数ALINC SI ;SI SI1,指向国名的第二个字母,指向国名的第二个字母LOOP MPR l ;CXCX1,若,若CX0,则循环到,则循环到MPR l,把国名的后两个字母,把国名的后两个字母,跟随第一个字母移动位置,直到跟随第一个字母移动位置,直到CX0为止,形成子程序的内循环控制为止,形成子程序的内循环控制POP SI ;现场恢复;现场恢复IPPOP CX ;现场恢复;现场恢复CSRET ;返回断点处;返回断点处MPR
46、0 ENDP ;子程序;子程序MPR 0结束结束*子程序结束子程序结束*CODE ENDSEND START第4章 程序设计方法【例【例4-9】每个国家的缩写名称,都用】每个国家的缩写名称,都用3个大写的英文字个大写的英文字母代表。比如母代表。比如CHA,USA,RUS及及AUS等。请将等。请将N个国家的缩写名称按字母的顺序进行排序。个国家的缩写名称按字母的顺序进行排序。分析问题:将分析问题:将N个国家的缩写名称按字母的顺序进行排个国家的缩写名称按字母的顺序进行排序,要反复进行序,要反复进行N1次比次比较,有时还要交换,最多较,有时还要交换,最多N1次。第一个字母比较完了,次。第一个字母比较完
47、了,其结果必然是第一个字母相同的国名排在一起。再其结果必然是第一个字母相同的国名排在一起。再对第二个字母比较,也要进行对第二个字母比较,也要进行N1次;第二个字母比次;第二个字母比较完了,再对第三个字母比较,再进行较完了,再对第三个字母比较,再进行N1次;可见,次;可见,这是循环嵌套问题。第一个字母比较是外循环,后这是循环嵌套问题。第一个字母比较是外循环,后面两次是内循环,次数都是面两次是内循环,次数都是N1次。每次循环中又嵌次。每次循环中又嵌套套“交换操作交换操作”的内循环。的内循环。第4章 程序设计方法4.3.2 约定存储单元法约定存储单元法 当需要传递的参数较多,只使用寄存器不能完成任务
48、,当需要传递的参数较多,只使用寄存器不能完成任务,这时可以考虑在内存数据段的存储单元中开辟专门这时可以考虑在内存数据段的存储单元中开辟专门的区域用于参数传递,让子程序直接访问数据段中的区域用于参数传递,让子程序直接访问数据段中的变量。主程序和子程序按照事先的约定,在指定的变量。主程序和子程序按照事先的约定,在指定的存储单元中进行数据交换。或者,把参数存放在的存储单元中进行数据交换。或者,把参数存放在数据段的存储单元中,将参数区的首地址存放在某数据段的存储单元中,将参数区的首地址存放在某个寄存器中,然后用寄存器传递参数的办法,把这个寄存器中,然后用寄存器传递参数的办法,把这个地址传递给子程序。个
49、地址传递给子程序。这种方式所能传递的参数数量几乎没有限制,其缺点是这种方式所能传递的参数数量几乎没有限制,其缺点是需要占用一定数量的存储单元,由于任何程序在任需要占用一定数量的存储单元,由于任何程序在任何时刻都可以修改这些数据,不利于模块化设计和何时刻都可以修改这些数据,不利于模块化设计和信息隔离。信息隔离。第4章 程序设计方法【例【例4-10】利用子程序结构,编写一个计算】利用子程序结构,编写一个计算S=1!+2!+7!+8!的程序。!的程序。分析问题:为了利用子程序结构,把计算任一正整数分析问题:为了利用子程序结构,把计算任一正整数i的阶乘的阶乘i!编写成为一个子程编写成为一个子程序。然后
50、在主程序中用不同的正整数调用它,并求它们的和。序。然后在主程序中用不同的正整数调用它,并求它们的和。确定算法:用子程序计算阶乘,因为要反复乘,采用循环程确定算法:用子程序计算阶乘,因为要反复乘,采用循环程序,循环次数是数的本序,循环次数是数的本身的值。用循环次数作为循环的控制条件,再配合使用身的值。用循环次数作为循环的控制条件,再配合使用JNZ指令。计算阶乘之和,放在外循环,循环次数已知,指令。计算阶乘之和,放在外循环,循环次数已知,8次,次,用循环次数作为循环的控制条件,再配合使用用循环次数作为循环的控制条件,再配合使用LOOP指令。指令。画程序流程图:略。画程序流程图:略。第4章 程序设计
51、方法确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要两个段:要两个段:数据段和代码段。如果形式上要完整一些,还可以再定义堆栈段。数据数据段和代码段。如果形式上要完整一些,还可以再定义堆栈段。数据段中至少定义段中至少定义2个变量,一个数组变量个变量,一个数组变量VARB,含有,含有8个数据,由题设个数据,由题设应选应选DB 类型,使用寄存器类型,使用寄存器SI定位;另一个变量是累加和定位;另一个变量是累加和SUM,选,选DW 类型。采用内外循环。内循环有子程序。类型。采用内外循环。内循环有子程序。 外循环次数的计数器外
52、循环次数的计数器用用CX,内循环次数的计数器用,内循环次数的计数器用DH。中间结果用寄存器。中间结果用寄存器AX,BX和和DL。有子程序,就有参数传递问题。入口参数用存储单元有子程序,就有参数传递问题。入口参数用存储单元VARB 并通过寄并通过寄存器存器SI传递,出口参数用传递,出口参数用AX传递。传递。编写程序,可以想得到,需要编写程序,可以想得到,需要MOV、ADD 、CMP 、JLE、INC、CALL、PUSH、POP和和LOOP等指令,最后要返回等指令,最后要返回DOS。未想到的,在编写过程中随时。未想到的,在编写过程中随时添加和修改,如添加和修改,如XOR指令等。由于每个国家的缩写名
53、称是指令等。由于每个国家的缩写名称是3个字母,个字母,因此要占用因此要占用3个字节存放。修改操作数的地址时要加个字节存放。修改操作数的地址时要加3,交换时最多要,交换时最多要交换交换N1次。并且要考虑到第三章所述关于多重循环的注意事项。交次。并且要考虑到第三章所述关于多重循环的注意事项。交换操作采用子程序完成。换操作采用子程序完成。第4章 程序设计方法具体程序如下:具体程序如下:DATA SEGMENTVARB DB 1,2,3,4,5,6,7,8SUM DW?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,
54、AXLEA SI,VARB ;送数组变量;送数组变量VARB的起始地址到寄存器的起始地址到寄存器SI,定位,定位 MOV CX,8 ;循环次数送入;循环次数送入CXXOR BX,BX ;BX清清0,存放阶乘之和,存放阶乘之和LOPl:CALL SUBP ;段内直接调用子程序;段内直接调用子程序SUBPADD BX,AX ;计算阶乘之和,寄存器;计算阶乘之和,寄存器AX存放数的阶乘存放数的阶乘INC SI ;SI SI1,指向下一个数,指向下一个数LOOP LOPl ;CX CX1,循环次数减,循环次数减1,若,若CX0,继续循环,直,继续循环,直到到CX0。MOV SUM,BX ;结果存入;结
55、果存入SUM字存储单元字存储单元MOV AH,4CH ;终止程序运行并返回;终止程序运行并返回DOSINT 2lH第4章 程序设计方法*子程序开始子程序开始*SUBP PROC ;定义;定义SUBP子程序,子程序,NEAR属性,可省略属性,可省略MOV DL,1 ;选寄存器;选寄存器DL,存放乘数,初值为,存放乘数,初值为1MOV AX,1 ;AX存放存放N!,初值为,初值为1MOV DH,BYTE PTRSI;循环次数送入寄存器;循环次数送入寄存器DHLOP2:MUL DL ;计算;计算N!INC DL ;乘数加;乘数加1DEC DH ;DH DH1,循环次数减,循环次数减1,若,若DH0,
56、继续循环,直,继续循环,直到到DH0。JNZ LOP2 ;循环乘;循环乘RET ;返回;返回SUBP ENDP ;子程序结束;子程序结束*子程序结束子程序结束*CODE ENDSEND START第4章 程序设计方法【例【例4-11】将一组分离】将一组分离BCD数转换为数转换为16位二进制数,试编写其程序。位二进制数,试编写其程序。分析问题:分离分析问题:分离BCD数,例如(数,例如(9)BCD00001001B,其中低四位是,其中低四位是该数的该数的BCD码,高码,高4位可以是任意的位可以是任意的0、1代码,比如说,可以是代码,比如说,可以是0000。而(。而(39)BCD000000110
57、0001001B,将它转换为二进制数为:,将它转换为二进制数为:27H00100111B= (000000111010) + (00001001)B,即等于即等于(分离(分离BCD数的高位字节)数的高位字节)10 + (分离分离BCD数的低位字节数的低位字节) 因为要对一组分离因为要对一组分离BCD数进行转换,需反复操作,故转换过程可以用数进行转换,需反复操作,故转换过程可以用子程序实现。但要注意主程序和子程序间的参数传递以及现场保护和子程序实现。但要注意主程序和子程序间的参数传递以及现场保护和恢复问题。恢复问题。 第4章 程序设计方法确定算法:采用子程序,并采用比较循环指令,循环次数是数组长
58、度确定算法:采用子程序,并采用比较循环指令,循环次数是数组长度LENG l。故。故用循环次数作为循环的控制条件,再配合使用用循环次数作为循环的控制条件,再配合使用LOOP指令。指令。画程序流程图:略。画程序流程图:略。确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少确定汇编语言程序的基本框架:可见,该汇编语言程序的基本框架至少要三个段:要三个段:堆栈段、数据段和代码段。堆栈段的存在是因为有现场保护和恢复问题,堆栈段、数据段和代码段。堆栈段的存在是因为有现场保护和恢复问题,定义定义256个字长度的堆栈空间。数据段中至少定义个字长度的堆栈空间。数据段中至少定义5个变量,它们依个变量,
59、它们依次是:次是:(1)待分离的)待分离的BCD数数BCD1,题目要求转换为,题目要求转换为16位二进制数,位二进制数,16位二位二进制数,其最大值是进制数,其最大值是215132767,那么一个待分离的,那么一个待分离的BCD数要占数要占45个字节。所以定义为:个字节。所以定义为: BCD1 DB 5 DUP(?)实际上,应该定义为实际上,应该定义为“5的倍数的倍数”个字节单元。本例从示例出发,只定个字节单元。本例从示例出发,只定义了义了5个字节。在实际运用时,应该定义为:个字节。在实际运用时,应该定义为: 待分离的待分离的BCD数的数目数的数目5个字节单元。个字节单元。第4章 程序设计方法
60、(2)变量)变量ADSEG,ADOFST,表示,表示BCD数的地址数的地址(包括段包括段地址和偏移地址地址和偏移地址),应选,应选DW 类型。使用寄存器类型。使用寄存器ES和和SI定定位。位。(3)变量)变量LENG l和和RESULT,用来表示,用来表示BCD数的长度及结数的长度及结果,应选果,应选DW 类型。类型。其中间结果放在寄存器其中间结果放在寄存器AX 和和BX。循环次数计数器用。循环次数计数器用CX。编写程序,可以想得到,需要编写程序,可以想得到,需要MOV、AND 、ADD 、DEC 、CBW、MUL 、PUSH、POP、CALL和和LOOP等指令。最后要返回等指令。最后要返回D
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 地理选择题试题及答案
- 初中还原试题及答案
- 中级会计实务大会考查试题及答案
- 仓库管理试题及答案
- 实战模拟中级会计实务考试试题及答案速查
- 财务管理常见陷阱指导试题及答案
- 单招全套试题及答案
- 单招本科试题及答案
- 财务管理考试成功心得试题及答案
- 学习财务心理学的个人计划
- 2025云南中考:物理必背知识点
- 2025年江苏省南京市玄武区中考一模历史试卷
- 2025年全国保密教育线上培训考试试题库及参考答案(完整版)及答案详解1套
- 西师大版小学五年级数学(下)期末测试题(带答案)
- Unit8SectionA1a2d课件人教版八年级英语下册
- 《社区多元主体协同治理研究的国内外文献综述》6700字
- 铝电解基础知识培训教材
- 2025年大学生人文知识竞赛题库及答案(完整版)
- 上诉状的课件
- 【合同范文】传媒公司合作合同6篇
- 乳腺癌防治知识手册运动与健康生活方式建议
评论
0/150
提交评论