汇编语言之程序的基本结构.docx

上传人:b****2 文档编号:613252 上传时间:2022-10-11 格式:DOCX 页数:41 大小:41.11KB
下载 相关 举报
汇编语言之程序的基本结构.docx_第1页
第1页 / 共41页
汇编语言之程序的基本结构.docx_第2页
第2页 / 共41页
汇编语言之程序的基本结构.docx_第3页
第3页 / 共41页
汇编语言之程序的基本结构.docx_第4页
第4页 / 共41页
汇编语言之程序的基本结构.docx_第5页
第5页 / 共41页
点击查看更多>>
下载资源
资源描述

汇编语言之程序的基本结构.docx

《汇编语言之程序的基本结构.docx》由会员分享,可在线阅读,更多相关《汇编语言之程序的基本结构.docx(41页珍藏版)》请在冰豆网上搜索。

汇编语言之程序的基本结构.docx

汇编语言之程序的基本结构

第6章程序的基本结构

在前面几章,我们分别介绍了用汇编语言进行程序设计所需要的几个最基本的知识:

存单元的寻址方式,变量定义和各种汇编指令格式。

在掌握了这些基本容之后,就需要学习如何把它们组成一个完整的汇编语言程序。

6.1源程序的基本组成

汇编语言源程序的组成部分有:

模块、段、子程序和宏等。

一个模块对应一个目标文件,当开发较大型的应用程序时,该程序可能由若干个目标文件或库结合而成的。

有关模块和子程序的知识和宏在第7章介绍,有关宏的知识将在第9章中叙述。

6.1.1段的定义

微机系统的存是分段管理的,为了与之相对应,汇编语言源程序也分若干个段来构成。

8086CPU有四个段寄存器,在该系统环境下运行的程序在某个时刻最多可访问四个段,而80386及其以后的CPU都含有六个段寄存器,于是,在这些系统环境下开发的运行程序在某个时刻最多可访问六个段。

不论程序在某个时刻最多能访问多少个段,在编程序时,程序员都可以定义比该段数更多的段。

在通常情况下,一个段的长度不能超过64K,在80386及其以后系统的保护方式下,段基地址是32位,段的最大长度可达4G。

段的长度是指该段所占的字节数:

、如果段是数据段,则其长度是其所有变量所占字节数的总和;

、如果段是代码段,则其长度是其所有指令所占字节数的总和。

在定义段时,每个段都有一个段名。

在取段名时,要取一个具有一定含义的段名。

段定义的一般格式如下:

段名

SEGMENT

[对齐类型] [组合类型] [类别]

;段的具体容

段名

ENDS

其中:

“段名”必须是一个合法的标识符,前后二个段名要相同。

可选项“对齐类型”、“组合类型”和“类别”的说明作用请见6.3节中的叙述。

一个数据段的定义例子:

DATA1

SEGMENT

word1

DW

1,9078H,?

byte1

DB

21,'World'

DD

12345678H

DATA1

ENDS

一个代码段的例子:

CODE1

SEGMENT

MOV

AX,DATA1

;把数据段DATA1的段值送AX

MOV

DS,AX

;把AX的值送给DS,即:

DS存储数据段的段值

MOV

AX,4C00H

INT

21H

;调用DOS功能,结束程序的运行

CODE1

ENDS

6.1.2段寄存器的说明语句

在汇编语言源程序中可以定义多个段,每个段都要与一个段寄存器建立一种对应关系。

建立这种对应关系的说明语句格式如下:

ASSUME 段寄存器名:

段名[,段寄存器名:

段名,……]

其中:

段寄存器是CS、DS、ES、SS、FS和GS,段名是在段定义语句说明时的段名。

在一条ASSUME语句中可建立多组段寄存器与段之间的关系,每种对应关系要用逗号分隔。

例如,

ASSUME CS:

CODE1,DS:

DATA1

上面的语句说明了:

CS对应于代码段CODE1,DS对应于数据段DATA1。

在ASSUME语句中,还可以用关键字NOTHING来说明某个段寄存器不与任何段相对应。

下面语句说明了段寄存器ES不与某段相对应。

ASSUME ES:

NOTHING

在通常情况下,代码段的第一条语句就是用ASSUME语句来说明段寄存器与段之间的对应关系。

在代码段的其它位置,还可以用另一个ASSUME语句来改变前面ASSUME语句所说明的对应关系,这样,代码段中的指令就用最近的ASSUME语句所建立的对应关系来确定指令中的有关信息。

例6.1汇编语言段及其段说明语句的作用。

DATA1

SEGMENT

;定义数据段DATA1

word1

DW 5678h

byte1

DB "ABCDEFG"

DATA1

ENDS

DATA2

SEGMENT

;定义数据段DATA2

word2

DW 1234h

word3

DW 9876h

DATA2

ENDS

DATA3

SEGMENT

;定义数据段DATA3

byte2

DB ?

DATA3

ENDS

CODE1

SEGMENT

;编写代码段CODE1

ASSUME

CS:

CODE1,DS:

DATA1,ES:

DATA2

;

(1)

MOV

AX,DATA1

;

(2)

MOV

DS,AX

;(3)

MOV

AX,DATA2

;(4)

MOV

ES,AX

;(5)

MOV

AX,word1

;访问段DATA1中的字变量word1

MOV

word2,AX

;访问段DATA2中的字变量word2

ASSUME

DS:

DATA3,ES:

NOTHING

;(6)

MOV

AX,DATA3

MOV

DS,AX

MOV

BL,byte2

;访问段DATA3中的字节变量byte2

MOV

AX,4C00H

;(7)

INT

21H

;(8)

CODE1

 ENDS

语句

(1)和(6)分别说明了段和段寄存器之间的对应关系,其中语句(6)重新说明语句

(1)所指定的对应关系。

二组语句

(2)和(3)、(4)和(5)实现对段寄存器DS和ES赋初值。

ASSUME说明语句只起说明作用,它不会对段寄存器赋值,所以,必须对有关段寄存器赋值。

在以后的其它源程序中也都是用此方法来实现对数据段寄存器赋值的。

语句(7)和(8)是调用中断21H的4CH号功能来结束本程序的执行,程序的返回代码由寄存器AL来确定。

结束本程序执行的指令是所有主模块必须书写的语句。

注意:

代码段寄存器不能由程序员在源程序中对其赋值,其值是由操作系统在装入它进入系统运行时自动赋值的。

6.1.3堆栈段的说明

堆栈段是一个特殊的段,在程序中可以定义它,也可以不定义。

除了要生成COM型执行文件的源程序外,一个完整的源程序一般最好定义堆栈段。

如果在程序中不定义堆栈段,那么,操作系统在装入该执行程序时将自动为其指定一个64K字节的堆栈段。

在程序没有定义堆栈段的情况下,在由连接程序生成执行文件时,将会产生一条如下的警告信息,但程序员可以不理会它,所生成的执行文件是可以正常运行的。

warningxxxx:

nostacksegment (其中:

xxxx是错误号)

在源程序中,可用以下方法来定义堆栈段。

方法1:

STACK1

SEGMENT

DB 256DUP(?

) 

;256是堆栈的长度,可根据需要进行改变

TOP

LABEL WORD

STACK1

ENDS

以上堆栈段的定义如图6.1所示。

由于堆栈是按地址从大到小的存储单元顺序来存放容的,所以,在堆栈存储单元说明语句之后,再说明一个栈顶别名,这样,对栈顶寄存器SP的赋值就很方便。

在源程序的代码段中,还要添加如下程序段,才能把段STACK1当作堆栈段来使用。

图6.1堆栈段定义示意图

ASSUME

SS:

STACK1

;可在代码段的段指定语句中一起说明

CLI

;禁止响应可屏蔽中断

MOV

AX,STACK1

MOV

SS,AX

MOV

SP,offsetTOP

;给堆栈段的栈顶寄存器SP赋初值

STI

;恢复响应可屏蔽中断

方法2:

STACK1

SEGMENT STACK

;定义一个堆栈段,其段名为STACK1

  DB 256DUP(?

STACK1

ENDS

上述段定义说明了该段是堆栈段,系统会自动把段寄存器SS和栈顶寄存器SP与该堆栈段之间建立相应的关系,并设置其初值,而不用在代码段对它们进行赋值。

除了以上二种方法外,还有一种更简洁的方法来定义堆栈段,有关容请见第6.4.2节中的叙述。

6.1.4源程序的结构

下面的程序是一个完整的源程序,其功能是在屏幕上显示字符串“Hello,World.”。

读者可参考此结构编写自己的简单程序。

例6.2在屏幕上显示字符串“HELLO,WORLD.”

解:

可运行下面的控件,用鼠标左键单击程序中的某一行,可阅读其含义;单击“存”可切换存容的显示方式。

伪指令END表示源程序到此为止,汇编程序对该语句之后的任何容都不作处理,所以,通常情况下,伪指令END是源程序的最后一条语句。

伪指令END后面可附带一个在程序中已定义的标号,由该标号指明程序的启动位置。

如果源程序是一个独立的程序或主模块,那么,伪指令END后面一定要附带一个标号;如果源程序仅是一个普通模块,那么,其END后面就一定不能附带标号。

6.2程序的基本结构

在学习高级语言程序设计时,我们知道了程序的三大主要结构:

顺序结构、分支结构和循环结构。

在汇编语言的源程序也同样有此三大结构,所不同的是它们的表现形式不同。

用高级语言编写程序时,由于不使用“转移语句”而使这三种结构清晰明了。

但在汇编语言的源程序中,很难不使用“转移语句”(除非是一些只有简单功能的程序),有时甚至会有各种各样的“转移语句”。

由于存在这些转移语句,就使得:

汇编语言源程序的基本结构显得不太明确。

如果源程序的编写者思维混乱,编写出来的源程序在结构上就会显得杂乱无章,反之,如果编写者条理清晰,安排的操作井然有序,那么,编写出来的程序在结构上就会一目了然。

总之,不论是高级语言的源程序,还是汇编语言的源程序,其程序的三大基本结构也还是万变不离其宗的。

6.2.1顺序结构

顺序结构是最简单的程序结构,程序的执行顺序就是指令的编写顺序,所以,安排指令的先后次序就显得至关重要。

另外,在编程序时,还要妥善保存已得到的处理结果,为后面的进一步处理直接提供前面的处理结果,从而避免不必要的重复操作。

例6.3编写程序段,完成下面公式的计算(其中:

变量X和Y是32位有符号数,变量A,B和Z是16位有符号数)。

A←(X-Y+24)/Z的商,B←(X-Y+24)/Z的余数

解:

DATA1

SEGMENT

X

DD ?

Y

DD ?

Z

DW ?

A

DW ?

B

DW ?

DATA1

ENDS

CODE1

SEGMENT

MOV

AX,X

MOV

DX,X+2

;用(DX:

AX)来保存32位变量X的数值

SUB

AX,Y

SBB

DX,Y+2

;(DX:

AX)-(Y+2:

Y)

ADD

AX,24D

ADC

DX,0

;(DX:

AX)+24

IDIV

Z

MOV

A,AX

MOV

B,DX

CODE1

ENDS

在编程序时,常常需要交换二变量之值。

假设需要交换值的变量名为:

var1和var2,临时增加的变量名为temp。

常用的算法如下:

temp=var1

var1=var2

var2=temp

例6.4假设有二个字变量word1和word2,编写程序段实现交换其值的功能。

解:

方法1:

用汇编语言指令简单“直译”上面的交换数据方法

DATA1

SEGMENT

word1

DW ?

word2

DW ?

temp

DW ?

DATA1

ENDS

CODE1

SEGMENT

MOV

AX,word1

MOV

temp,AX

;上二语句实现语句“temp=word1”

MOV

AX,word2

MOV

word1,AX

;上二语句实现语句“word1=word2”

MOV

AX,temp

MOV

word2,AX

;上二语句实现

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1