首页 理论教育 微型计算机原理:程序结构伪操作

微型计算机原理:程序结构伪操作

时间:2023-11-03 理论教育 版权反馈
【摘要】:DWORD一般用于运行在80386及后继机型上的程序。除了TITLE伪操作之外,程序还可以用NAME伪操作来定义程序模块的名字。

微型计算机原理:程序结构伪操作

1.段定义伪操作

段定义伪操作SEGMENT和ENDS用来表示一个段的开始和结束,格式如下:

978-7-111-46342-9-Chapter03-12.jpg

其中,seg_name是由程序员所命名的段名,在SEGMENT伪操作和ENDS伪操作中seg_name必须一致。options是提供给汇编程序用来定位和组织段的相关信息,但是这些信息不是必须提供的,在书写纯汇编语言程序的时候经常被省略。在SEGMENT和ENDS伪操作之间可以包括各种汇编语句,包括汇编语言指令、伪指令和宏指令。

需要注意的是,虽然段的命名是任意的,段名并不表示段的用途,但是一般情况下对于堆栈段、数据段和代码段,我们还是习惯性地用STACK、DATA、CODE、TEXT之类的名字作为其段名,这样对于阅读理解和防止出错更加有利。

同时,不同用途的段所包括的内容一般情况下也是不一样的。堆栈段一般用作过程调用、中断现场保存等操作的暂存区使用,因而其内容一般很简单,只要用DB一类的数据定义指令保留一段存储区即可。数据段一般用来存储数据,其中一般包括一系列的数据定义指令,用来定义程序运行过程中需要的数据。而代码段一般用来存储代码,其中是一系列的过程定义、汇编指令和宏指令等,有时代码段中也会出现一些数据定义,如我们在本节开头的示例程序中的代码段。

段定义伪操作的options域用来表示关于段定义的一些类型特性,主要包括其定位类型和组合类型。一般情况下,这些说明可以不用,但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要提供类型和属性的说明。可用的关键字见表3-2。

3-2 定位类型

978-7-111-46342-9-Chapter03-13.jpg

定位类型用于说明段的起始边界值(物理地址),其默认项是PARA,即在未指定定位类型的情况下,则连接程序默认为PARA。BYTE和WORD用于把其他段(通常是数据段)连入一个段时使用。DWORD一般用于运行在80386及后继机型上的程序。

组合类型(见表3-3)用于说明程序连接时的段组合方法,其默认项为PRIVATE。

3-3 组合类型

978-7-111-46342-9-Chapter03-14.jpg

2.段分配伪操作

既然段定义伪操作中的段名并不表示段的用途,而不同用途段(代码段、数据段、堆栈段)的定义又各不相同,就必须存在一种方法来指明定义的各个段的用途是什么,这就是段分配伪操作。

段分配伪操作的格式如下:

ASSUME段寄存器名:段名[,段寄存器名:段名]

ASSUME伪操作的作用是把程序中的各个段分配给段寄存器,使程序中使用的段名和段寄存器之间建立起对应关系。ASSUME语句在汇编程序中是不可省略的,而且程序中所有定义的段,在ASSUME中都必须包括对应段寄存器的段分配语句。这是因为在一个汇编语言程序中可能有多个代码段、多个数据段和多个堆栈段,而对每一种段CPU只有一个段寄存器,也就是说,在同一时刻CPU只能对其中的一个段进行寻址操作,这就需要ASSUME来告诉汇编程序,CPU在计算存储器地址时应该使用哪个段的段地址。需要注意的是,AS-SUME只是将设置当前段的情况传递给汇编程序,并不实际装载段寄存器,除了CS寄存器的值能够在连接和装入的时候自动装载之外,其他段寄存器的值必须在程序中使用MOV指令(以后会详述)来装入,例如:

978-7-111-46342-9-Chapter03-15.jpg(www.xing528.com)

上面程序段将DATA段的段地址装入到DS寄存器,如果要装入到ES寄存器也可以用类似的语句段来实现。需要注意的是,DS寄存器不能直接装入立即数,必须使用通用寄存器AX、BX……来进行“中转”。

3.过程定义伪操作

和很多高级语言都有过程、函数的概念一样,在汇编语言中同样也有过程的概念。汇编语言中的过程是用过程定义伪操作来定义的,其格式如下:

978-7-111-46342-9-Chapter03-16.jpg

在汇编语言中,过程指的是用来完成某一特定功能的一组指令。(思考一下,过程定义应该在哪些段定义的定义体内部?代码段,数据段还是堆栈段?)每一个过程需要定义一个过程名,这个过程名可以被视为是过程的一个入口,它对应的地址就是过程中第一条指令的地址。需要注意的是,对应的PROC伪操作和ENDP伪操作应该具有相同的过程名。根据过程调用方式的不同,伪操作PROC可以带有类型属性NEAR或FAR(即近调用和远调用),用来表示过程和过程的调用者(或者说子程序和子程序的调用者)是否处于同一个代码段。如果不给定NEAR或FAR类型属性,则默认为NEAR。一般情况下作为整个程序入口的主过程是由操作系统在完成程序的装载和初始化后调用的,这次调用必然是跨代码段的调用,所以主过程应当被定义为FAR类型。

还有一点需要记住的是,和C语言中的函数定义一样,汇编语言的过程定义也不支持嵌套定义,也就是说,在一个过程定义体的内部不能再定义另一个过程。

4.列表输出伪操作

和前面介绍的几个伪操作不同,列表输出伪操作并不对生成的二进制代码有任何影响,它们是为了改善列表输出文件,即LST文件的可读性而使用的。列表输出伪操作主要有两个:PAGE和TITLE。

PAGE伪操作用来告诉打印机以多少行和多少列的格式来打印文件,其格式为:

PAGE行,列

其中行数的范围为10~255,默认值为66。列数的范围为60~132,默认值为80。

当列表文件多于一页时,汇编程序能够在每页的顶部打出程序的标题,标题的定义就依靠TITLE伪操作。TITLE伪操作非常简单,在TITLE伪操作符后面直到行末尾的部分都将作为程序的标题而被打印在每页的顶部。TITLE伪操作定义的标题应该由不多于60个ASCⅡ字符组成,一般用来说明程序的原理、用途、开发者等信息。

除了TITLE伪操作之外,程序还可以用NAME伪操作来定义程序模块的名字。如果一个程序模块没有用NAME或TITLE定义其模块名,则源程序的文件名将成为该程序模块的模块名。

5.程序结束伪操作

程序结束伪操作位于整个程序的结尾,用来标识整个程序的结束。程序结束伪操作的格式如下:

END[标号]

在END之后的标号给出了程序的入口地址,即程序从哪里开始运行。如果程序中定义了主过程的话,这个入口地址一般就是主过程名。如果在END后面没有标号,则意味着程序不能单独运行,而作为一个子模块提供给其他程序调用。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈