汇编语言程序设计第6章
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第6章 子 程 序 设 计
该指令先把返回地址(即主程序中CALL指令的下一条指令 的地址)保存到堆栈中,以便子程序执行完返回主程序时使用, 然后则转移到子程序的入口地址去执行子程序。指令中的DST 一般是过程名(被调用过程),即子程序入口的符号地址,D16是 子程序入口地址和CALL指令之间的偏移量。
第6章 子 程 序 设 计 6.2.2 子程序调用方法说明
一个完整的子程序,应当包括子程序调用方法说明、保护现 场和恢复现场、子程序定义等部分。为了使用的方便,子程序应 以文件形式编写。子程序文件由子程序说明和子程序本身构成。 子程序说明部分要求语言简明、确切。
子程序说明一般由如下几部分组成: (1) 功能描述:包括子程序的名称、功能、性能指标(如执 行时间)等。 (2) 所用的寄存器和存储单元。 (3) 子程序的入口、出口参数。 (4) 子程序中又调用的其他子程序。 (5) 调用实例。
第6章 子 程 序 设 计
2.重复性 子程序是可多次重复使用的。—个子程序只占一段存储空 间,但可以多次地调用它,这样就避免了编程人员的重复劳动, 节省了存储空间。由于增加了调用、返回指令以及现场保护, 因此程序执行时间会增长。如果一个程序段只用到一次,就没 有必要编写成子程序形式。
第6章 子 程 序 设 计
RET SUBA ENDP SUBB PROC FAR
…
SUBB CODEB
RET ENDP ENDS END
MAIN
第6章 子 程 序 设 计
由于SUBB既被段间调用又被段内调用,所以必须是FAR属性。 例6-2给出的子程序SUBA、SUBB与主程序MAIN不在同一代码 段中,主程序MAIN在CODEA代码段中,而子程序SUBA、SUBB在 CODEB代码段中。 例6-1和例6-2说明,汇编语言程序中的主、子程序,既可 以在同一个代码段中(如例6-1),也可以在不同的代码段中(如 例6-2)。
第6章 子 程 序 设 计
6.2 子程序的结构形式
6.2.1 子程序的定义 子程序必须经过定义以后才能被调用。其定义格式如下: 过程名 PROC 类型属性
;过程体 过程名 ENDP 功能:实现子程序的定义。
…
第6章 子 程 序 设 计
说明:
(1) PROC和ENDP是过程的定义符和结束符,它们必须成对 出现,它们前面的过程名必须一致,过程名为一标识符,它的 写法和标号的写法相同,它实际上是子程序入口的符号地址。
01 (IP)
0500H 0501H 0502H 0503H
…
SUBR1
0603H
…
(a)
(b)
(c)
图6-3 段内直接调用指令CALL执行示意图
第6章 子 程 序 设 计
本例中执行CALL SUBR1时,自动将返回地址(IP)=0503H, 入栈保存,然后执行(IP)+D16=0503H+0100H=0603H→IP,转 到子程序SUBR1去执行。
3.可重定位性
可重定位性是指子程序可以存放在存储区的任何地址处。 如果子程序只能存放在固定的地址处,则在编写主程序时要特 别注意存储单元的分配,不要使主程序占用了子程序的存储单 元而破坏子程序,这样就会给编程人员带来很大麻烦,而且在 装配主程序和子程序时往往造成存储空间的冲突或浪费。为了 使子程序可重定位在内存的任意区域中,编制子程序时,不应 采用绝对地址,而应全部使用相对地址。
1) 调用程序和子程序在同一个代码段的程序结构
若调用程序和子程序在同一个代码段内,其程序框架如例6-1 所示。此程序给出了代码段中含有主程序和一个子程序的情况, 实际上可以含有多个子程序,子程序可以是NEAR型或缺省。注 意段长不能超过64 KB。
第6章 子 程 序 设 计
例6-1 CODE MAIN
SEGMENT PROC FAR PUSH DS MOV AX,0 PUSH AX
……
CALL SUBA
RET
;其他代码
第6章 子 程 序 设 计
MAIN SUBA
ENDP PROC
…
RET
SUBA
ENDP
CODE
ENDS
END MAIN
例6-1的子程序SUBA与主程序MAIN同处在一个代码段CODE之中。
图6-3中:(a)图是CALL SUBR1执行前堆栈;(b)图是CALL SUBR1执行后堆栈;(c)图是CALL SUBR1机器指令格式示意图。
第6章 子 程 序 设 计 2.段内间接调用 格式:CALL DST
CALL WORD FAR DST 其中:DST为通用寄存器或字存储器。 功能:将子程序的返回地址(断点地址)存入栈中,并转移 到子程序的入口地址执行子程序。 执行的操作:(SP)-2→SP
(IP) →(SP)+1,(SP) (EA) →IP 其中,EA是由DST的寻址方式所确定的有效地址。
第6章 子 程 序 设 计
例6-4 CALL DX
;子程序的入口地址存于寄存器DX中
CALL WORD PTR[SI] ;子程序的入口地址在存储单元中
第6章 子 程 序 设 计
例6-3 CODE
SEGMENT MAIN PROC FAR
……
CALL SUBR1
MAIN ENDP SUBR1 PROC NEAR
…SUBR1 ENDP COD Nhomakorabea ENDS
第6章 子 程 序 设 计
堆栈 (SP)
(IP)
堆栈
03 05
代码段
…
FF CALL SUBR1 00
例6-2 CODEA MAIN
SEGMENT PROC PUSH MOV PUSH
CALL
FAR DS AX,0 AX
FAR PTR
SUBB
;其他代码
……
MAIN CODEA
RET ENDP ENDS
第6章 子 程 序 设 计 CODEB SEGMENT SUBA PROC FAR
……
CALL FAR PTR SUBB
6.1.2 子程序的分类
子程序的种类很多,有单入口、单出口子程序,也有多入 口、多出口子程序。对于一些复杂的子程序,还常常要调用别 的子程序。这种调用可以是一个子程序调用另外的一个子程序, 也可以是一个子程序调用自身,这就形成了嵌套结构和递归结 构,分别称为嵌套子程序和递归子程序。子程序嵌套的示意图 如图6-2所示。
第6章 子 程 序 设 计
第6章 子 程 序 设 计
6.1 子程序的概念与特性 6.2 子程序的结构形式 6.3 子程序调用和返回指令 6.4 子程序的设计 6.5 子程序的参数传递方法 6.6 子程序的嵌套与递归 6.7 综合举例
第6章 子 程 序 设 计
6.1 子程序的概念与特性
6.1.1 子程序的概念
第6章 子 程 序 设 计
6.3 子程序调用和返回指令
6.3.1 调用指令 1.段内直接调用 格式:CALL DST CALL NEAR PTR DST 功能:将子程序的返回地址(断点地址)存入栈中,并转移
到子程序入口地址去执行子 程序。
执行的操作: (SP)-2→SP (IP)→(SP)+1,(SP) (IP)+ D16→IP
第6章 子 程 序 设 计
4.可递归性 前面已提及递归程序的概念。在图6-2中,当子程序1和子 程序2是同一个程序时,这种调用就是递归调用。为使子程序具 有可递归性,应当利用堆栈和寄存器作为中间结果的暂存器, 而不能用固定的存储单元做暂存器。
第6章 子 程 序 设 计
5.可重入性
可重入性是指子程序可被中断并能再次被中断程序调用。 具体地讲就是,如果子程序可被中断,在中断处理中又被中断 服务程序调用,并且能为中断服务程序和中断了的子程序提供 正确的结果,这种子程序就是可重入的。同样,为使子程序具 有可重入性,也应当利用堆栈和寄存器作为中间结果的暂存器, 而不能用固定的存储单元做暂存器。
第6章 子 程 序 设 计
例如,有一子程序说明如下: ; 子程序 DTOB ; 将两位十进制数(BCD码)转换成二进制数 ; 入口参数:AL寄存器中存放十进制数 ; 出口参数:CL寄存器中存放转换完的二进制数 ; 所用寄存器:BX ; 执行时间:0.06 ms
第6章 子 程 序 设 计
看了这一子程序说明,尽管还不知道子程序本身的情况, 但根据说明已可以调用这个子程序了。该子程序说明的第一、 二行告诉我们DTOB子程序完成的功能。入口参数说明这一程序 在调用前应将要转换的十进制数送入AL寄存器。出口参数说明, 子程序执行完后,转换结果就在CL寄存器中,所用寄存器是说 该子程序执行过程中要用到BX寄存器,因此在调用本子程序前, 若BX寄存器里存放着有用数据的话,应该事先转存或保护起来, 否则可能会被破坏。执行时间则说明了该程序执行所需的时间 是0.06 ms。有的说明中还给出一个调用实例,以实例的形式教 给用户如何使用和调用子程序。
第6章 子 程 序 设 计
2) 调用程序和子程序在不同代码段的程序结构 若调用程序和子程序在不同的代码段中,其程序框架如例 6-2所示。其中的子程序为FAR属性,CALL指令显式说明其FAR 属性。此程序只给出了一个模块内的多个代码段的情况,也可 将程序设计为多模块的情况。
第6章 子 程 序 设 计
人们在编写程序时,常常会遇到这样的情况:某些完成相 同的功能,只是加工的数据略有不同的指令组(程序段)需要在 一个程序的若干不同地方使用多次,或是在一个程序中的多个 地方或多个程序中的多个地方用到了同一段程序。这些程序段 的功能和结构形式都相同,只是某些变量的赋值不同。那么就 可以将这段程序抽取出来存放在某一存储区域,每当需要执行 这段程序时,就转到这段程序去执行,执行完后再返回到原来 的程序继续运行。把抽取出来的这段具有特定功能的程序段称 为子程序。
第6章 子 程 序 设 计
例如,计算某个数的立方根可能在一个程序中使用多次,但 每次自变量不同。又如,设计名字识别程序时,有时需要判断字 符是否为字母,有时又需要判断字符是否为分隔符。这样的指令 组所包含的指令,少则几条十几条,多则数十条几百条。如果每 一处都重复把它写一次,这显然太浪费程序设计的时间和计算机 的存储空间。但这又不能设计成循环程序。因此,人们通过实践, 在程序设计的早期就想出了一种较好的办法,就是把这组指令分 离出来,单独写成一个所谓的“子程序”,并建立进入它和从它 出来时所需要的连接信息。只需在需要处调用这个子程序就行。 换言之,子程序方法使得人们把“多次编写”的情况转变成“一 次编写,多次调用”的情况。子程序相当于高级语言中的过程或 函数。
第6章 子 程 序 设 计
通常,把要调用程序的那个程序称为主程序或调用程序,也 称转子;而把被调用的程序称为子程序或被调用程序,也称返主。 把它们之间控制的转移称为子程序的连接。主程序与子程序的关 系如图6-1所示。
转子 主 程 序
子 程 序
返主
图6-1 主程序与子程序的关系
第6章 子 程 序 设 计
(2) 类型属性可以是NEAR或FAR两种类型,缺省时为NEAR属 性。过程属性的确定方法是当调用过程(主程序)和被调用过程 (子程序)在同一个代码段中则用NEAR属性;当调用过程和被调 用过程不在同一个代码中则使用FAR属性。
第6章 子 程 序 设 计
(3) 在子程序设计中,除了子程序必须经过定义以外,还 必须解决主程序和子程序的链接、主程序和子程序的参数传递 这两个问题。主程序和子程序的链接是通过执行调用指令和返 回指令实现的,而主程序和子程序的参数传递可有多种方式, 这将在6.5节中讨论。先讨论第一个问题。
在程序设计的实际应用中,子程序的引入可以节省存储空 间及程序设计所花费的时间,有利于设计一个大而复杂的程序, 即把一个大而复杂的程序设计成一个主程序和若干个子程序。 这有助于减少程序的复杂性,便于模块化设计,也便于程序的 调试及修改等。但子程序也有其不足之处,这就是要多花费一 些机器时间。
第6章 子 程 序 设 计
第6章 子 程 序 设 计
主 程 序
子 程 序
子 程 序
1
2
图6-2 嵌套子程序示意图
第6章 子 程 序 设 计
6.1.3 子程序的特性 1.通用性 子程序具有通用性,便于共享。例如,键盘管理程序,磁
盘读写程序,标准函数程序等等,许多程序中要用到这些程序, 这种可共享的程序最适宜写成子程序。而只能完成特定功能的 子程序,由于缺乏通用性,难于共享,就不适宜写成子程序。