设计指令系统及汇编语言程序设计.docx

上传人:b****5 文档编号:4530411 上传时间:2022-12-01 格式:DOCX 页数:32 大小:48KB
下载 相关 举报
设计指令系统及汇编语言程序设计.docx_第1页
第1页 / 共32页
设计指令系统及汇编语言程序设计.docx_第2页
第2页 / 共32页
设计指令系统及汇编语言程序设计.docx_第3页
第3页 / 共32页
设计指令系统及汇编语言程序设计.docx_第4页
第4页 / 共32页
设计指令系统及汇编语言程序设计.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

设计指令系统及汇编语言程序设计.docx

《设计指令系统及汇编语言程序设计.docx》由会员分享,可在线阅读,更多相关《设计指令系统及汇编语言程序设计.docx(32页珍藏版)》请在冰豆网上搜索。

设计指令系统及汇编语言程序设计.docx

设计指令系统及汇编语言程序设计

【关键字】设计

指令系统及汇编语言程序设计

2.4伪指令

伪指令本身不会产生可执行的机器指令代码,它仅仅是告诉汇编程序有关源程序的某些信息,或者用来说明内存单元的用途。

伪指令在汇编过程中由汇编程序进行处理。

数据定义伪指令

数据定义伪指令用于定义变量的类型、给保存器赋初值或给变量分配保存单元。

常用的数据定义伪指令有DB、DW和DD等。

格式:

[变量名]伪指令助记符数据表项

功能:

定义一个数据保存区,其类型由所定义的数据定义指令而指定。

操作说明:

方括号中的变量名为任选项,变量名后面不跟冒号“:

”。

数据表项可以包含多个数据之间用逗号分隔开。

数据定义伪指令助记符有以下三种:

(1)DB定义变量类型为字节(BYTE),DB后面的每个数据占一个字节。

(2)DW定义变量类型为字(WORD),DW后面的每个数据占一个字,即两个字节。

在内存中,低字节在前,高字节在后。

(3)DD定义变量类型为双字(DWORD),后面的每个数据占两个字。

在内存中,低位字在前,高位字在后。

例如,有下列数据定义语句

D1DB1,-12

D2DW1,2010H

D3DD1,H

数据表项中除了常数、表达式和字符串外,还可以是问号“?

”,它仅给变量保留相应的保存单元,而不给变量赋初值。

相同的操作数重复出现时,可用重复符号“DUP”表示。

其格式为:

nDUP(初值[,初值,……]);n表示重复的次数,圆括号中为重复的内容。

下面是用问号或DUP表示操作数的例子:

ARRAYDB1000DUP(0)

VARDW?

,?

符号定义伪指令

1.赋值伪指令

格式:

变量名EOU表达式

功能:

将右边表达式的值赋给左边的变量。

操作说明:

表达式可以是一个常数、符号、数值表达式或地址表达式。

需要注意的是:

EQU伪指令不允许对同一符号重复定义。

EQU伪指令具体应用举例如下:

CREQUODH;定义CR为常数(回车的ASCII代码)

TABEQUTABLE-ASCII;定义变量

DISEQU1024*768;定义数值表达式

ADREQUES:

[DI+3];定义地址表达式

MEQUMOV;定义助记符

2.等号(=)伪指令

格式:

变量名=表达式

功能:

将右边表达式的值赋给左边的变量。

操作说明:

等号(=)伪指令的功能与EQU伪指令相仿,它可以对同一个名字重复定义。

利用等号(=)伪指令可以使程序设计更加灵活。

例如下面的程序段:

TABLE=1

MOVAX,TABLE

RRRR:

ADDAX,1

TABLE=TABLE+1

MOVAX,TABLE

CMPAX,100

JNERRRR

3.定义符号名伪指令LABEL

格式:

符号名LABEL类型

功能:

定义一个标号或变量名,并指定其类型。

操作说明:

其中符号名可以是标号或变量,LABEL伪指令通常要与指令语句或DB、DW、DD伪指令语句连用。

与指令连用时,类型属性有NEAR和FAR两种;与DB等伪指令语句连用,可以使同一个数据区既有BYTE属性,又有WORD属性和DWORD属性,这样在以后的程序中根据不同的需要分别以字节或字为单位存取其中的数据。

LABEL伪指令具体使用如下:

DATAWLABELWORD;变量DATAW类型为WORD

DATABDB20DUP(?

);变量DATAB类型为BYTE

MOVDATAW,AX;按字存入

MOVDATAB[2],AL;按字节存入

LABEL伪指令也可以将属性已经定义为NEAR的标号再定义为FAR属性。

例如:

ABCFLABELFAR;过程入口(远程调用)

ABCMOVAX,0000H;过程入口(段内调用)

上面的过程既可用标号ABC在本段调用,也可以用标号ABCF被其他段调用。

2.4.3段定义伪指令

段定义伪指令在汇编语言源程序中定义逻辑段。

常用的段定义伪指令有ASSUME、SEGMENT和ENDS等。

1.段定义伪指令SEGMENT和ENDS

SEGMENT和ENDS伪指令用于定义一个逻辑段,给逻辑段赋予—个段名,并在后面的任选项中给出这个逻辑段的其他特性,如定位类型、组合类型和类别。

段定义伪指令格式如下:

段名SEGMENT[定位类型][组合类型][‘类别’]

段名ENDS

说明:

SEGMENT伪指令定义一个逻辑段的开始,ENDS伪指令则表示一个逻辑段的结束,这两个伪指令总是成对出现,而且前面的段名必须一致。

两个伪指令语句之间的部分是该逻辑段的内容。

汇编语言的逻辑段包括代码段、数据段和堆栈段等。

代码段主要是程序指令和某些伪指令;数据段用于定义数据和存储单元;堆栈段为堆栈操作预留出存储空间。

SEGMENT伪指令后面可以有三个任选项:

1)定位类型定位类型任选项是告诉汇编程序如何确定逻辑段的边界在存储器中的位置,定位类型有四种:

①BYTE表示逻辑段边界可以从任何一个字节开始。

②WORD表示逻辑段边界从字地址开始,这样该逻辑段的起始地址必须是偶数。

③PARA表示逻辑段边界从节地址开始,16个字节称为一个节。

如果省略定位类型任选项,汇编语言程序默认该逻辑段为PARA。

④PAGE表示逻辑段边界地址从页边界开始,256个字节称为一个页。

2)组合类型SEGMENT伪指令的第二个任选项是组合类型,它告诉连接程序,装入存储器时各个逻辑段如何进行组合。

组合类型有6种。

①NONE此项为不组合,如果编程时省略SEGMENT伪指令的组合类型。

②PUBLIC汇编程序连接时,将不同程序模块中具有相同的类别名的逻辑段顺序连接成一个逻辑段装入内存。

③STACK组合类型为STACK时,编译程序把所有同名段连接成一个连续的堆栈段。

④COMMON该组合类型产生一个覆盖段。

模块连接时,如果有相同的类别名,则都从同一个地址开始装入,因而连接的逻辑段将发生重叠。

连接以后段的长度等于原来最长的逻辑段的长度,重叠部分的内容是最后一个逻辑段的内容。

⑤MEMORY组合类型为MEMORY时,表示本段在存储器中应定位在所有其他段的最高地址。

⑥ATAT组合类型表示本段可以定位在表达式所指示的边界上。

如:

AT0830H;本段的地址从0830H开始。

3)类别名类别名必须用单引号括起来,类别名可由程序设计人员自己选定任何字符串组成,但它不能再作为程序的标号,变量名或其他定义的符号。

在连接处理时,LINK程序把类别名相同的所有段存放在连续的存储区内。

下面是一个分段结构的源程序框架:

DATAlSEGMENT

DATAlENDS

STACK1SEGMENTPARASTACK

STACK1ENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATAl,SS:

STACKl

BEGIN:

……

CODEENDS

ENDBEGIN

2.指定段址伪指令ASSUME

格式:

ASSUME段寄存器名:

段名[,段寄存器名:

段名,……]

功能:

指定段寄存器与某个逻辑段建立对应关系。

操作说明:

其中段寄存器名是指四个段寄存器CS、SS、DS、ES中的一个,段名是指逻辑段的段名。

需要注意的是:

ASSUME伪指令只是告诉汇编程序段寄存器与逻辑段的关系,并没有给段寄存器赋予实际的初值。

若要给段寄存器赋值,可参考下面程序:

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA1,SS:

STACKl

MOVAX,DATA1

MOVDS,AX

MOVAX,STACKl

MOVSS,AX

CODEENDS

2.4.4过程定义伪指令

程序设计中,我们常常把具有一定功能的程序段设计成一个子程序。

汇编程序用“过程”来构造子程序。

格式:

过程名PROC[NEAR/FAR];NEAR与FAR只选一个,或都不选

RET

过程名ENDP

功能:

定义一个过程(子程序)。

操作说明:

其中,过程名不能省略,过程的开始和结束应使用同一个过程名。

过程名也就是子程序的程序名,可以通过CALI指令调用,它类同于一个标号的作用,具有三个属性:

段、偏移量和类型。

类型可以选择NEAR或FAR,如果没有选择距离类型,则默认为NEAR。

2.4.5定位伪指令ORG和当前位置计数器$

格式:

ORG数值表达式

功能:

指定在它之后的程序段或数据块所存放的单元起始地址的偏移量。

当前地址计数器‘$’它表示当前地址,即地址计数器的值。

例如:

DATASEGMENT

ORG20H

D1DB12H,13H

ORG$+01H

D2DB61H,62H,63H

DATAENDS

CODESEGMENT

ASSUMECS:

CODE,……

ORG100H

BEGIN:

MOVAX,DATA

CODEENDS

上面的数据段中,D1的段内偏移量为0020H而不是0000H,D2的段内偏移量是0023H。

代码段里,指令代码从偏移量0100H处开始。

2.4.6结束汇编指令END

格式:

END标号

功能:

通知汇编程序结束汇编。

操作说明:

标号为主程序执行时的入口标号。

注意,该指令并表示执行程序结束,只是汇编程序结束汇编。

而要计算机停止执行程序而退回到DOS操作系统,需用DOS调用:

MOVAH,4CH

INT21H

第2章指令系统及汇编语言程序设计

2.5汇编语言程序设计

2.5.1汇编语言程序

1.汇编语言的基本概念

使用助记符号来表示二进制格式的指令代码和变量地址的指令称为符号指令。

汇编语言程序运行之前要将其转换成机器代码,转换的过程是由编译程序完成。

2.汇编语言源程序的格式

汇编语言源程序采用分段式结构,一个汇编语言源程序由若干个逻辑段组成,每个逻辑段以SEGMENT语句开始,以ENDS语句结束,整个源程序以END语句结束(表示结束汇编)。

下面给出一个简单的汇编语言源程序。

DATASEGMENT;定义一个名字为DATA的段

DATDB1,2,0;在DATA段内定义3字节数据

DATAENDS;DATA段结束

;---------------------------------------------------------

STACKSEGMENTPARASTACK;定义名字为STACK的堆栈段

DW20DUP(0);堆栈段大小为20个字

STACKENDS;堆栈段结束

;---------------------------------------------------------

CODESEGMENT;定义一个名为CODE的程序代码段

ASSUMECS:

CODE,DS:

DATA,SS:

STACK

BEGIN:

MOVAX,DATA

MOVDS,AX;给DS赋数据段初值

MOVAL,DAT

ADDAL,DAT+1;前两个数据相加

MOVDAT+2,AL;和存入第三个数据的位置

MOVAH,4CH

INT21H;使用系统调用返回操作系统

CODEENDS;代码段结束

;----------------------------------------------------------

ENDBEGIN;源程序结束,入口地址为BEGIN

从上面的例子可以看出,汇编语言源程序由若干段组成,最上面是数据段,接下来是堆栈段,最后是代码段。

2.5.2顺序程序设计

顺序结构是解决简单问题的一种程序设计方法,它按语句书写的先后次序执行一系列操作。

程序中没有分支、循环和转移指令。

顺序结构程序在设计上比较简单,这种程序也称为直线程序。

下面举例对顺序结构程序的设计作具体说明。

【例2.54】对两个4位十进制数进行求和运算,十进制数用BCD码表示(1234+5678)。

解:

根据题意,在程序的数据段放置BCD码形式的十进制数。

在计算中考虑到多位运算,高位使用带进位加法指令,并注意进行十进制加法调整。

程序如下:

DATA1SEGMENT

DATlDB12H,34H

DAT2DB56H,78H

SUMDB?

,?

DATA1ENDS

STACKlSEGMENTPARASTACK

DW20DUP(0)

STACKlENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA1,SS:

STACK1

BEGIN:

MOVAX,DATA1

MOVDS,AX

MOVAL,DAT1+1

ADDAL,DAT2+1

DAA

MOVSUM+1,AL

MOVAL,DAT1

ADCAL,DAT2

DAA

MOVSUM,AL

MOVAH,4CH

INT21H

CODEENDS

ENDBEGIN

【例2.55】试编制汇编语言程序,并按公式Z=((X+Y)*8-X)/4计算Z值,并将结果保存在RESULT中。

分析:

按题意,本题为典型的顺序结构。

在已知X、Y的情况下,只需按公式计算Z值即可,故在数据段设定了X、Y的值。

编制程序如下:

DATA1SEGMENT

XDW2

YDW4

RESULTDW?

DATA1ENDS

STACKlSEGMENTPARASTACK

DW20DUP(0)

STACKlENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA1,SS:

STACK1

BEGINMOVAX,DATA1

MOVDS,AX

MOVBX,X

ADDBX,Y

MOVCL,3

SALBX,CL

SUBBX,X

MOVCL,2

SARBX,CL

MOVRESULT,BX

MOVAH,4CH

INT21H

CODEENDS

ENDBEGIN

2.5.3分支程序设计

1.分支程序设计的结构形式

分支程序结构形式如图2.16所示。

其中(a)、(b)为二分支结构,(c)为多分支结构。

2.分支程序的设计方法

测试分支程序设计方法:

选用影响状态标志的指令和条件转移指令来设计分支程序的方法。

跳转表法分支程序设计方法:

选用间接寻址的无条件转移指令来选择转向不同的程序分支。

(1)测试法分支程序设计

【例2.56】设有单字节无符号数X、Y、Z,若X+Y>255,则求X+Z,否则求X-Z,运算结果放在F1中。

分析:

因为X,Y均为无符号数,所以当X+Y>255时则会产生进位,即CF=1,所以可以用进位标志来判断。

程序流程图如图2.17所示。

程序段如下:

;…………数据段…………

DATASEGMENT

XDB128

YDB90

ZDB50

F1DB?

DATAENDS

;…………代码段…………

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA

START:

MOVAX,DATA

MOVDS,AX

MOVAL,X

ADDAL,Y

JCP1

MOVAL,X

SUBAL,Z

JMPEXIT

P1:

MOVAL,X

ADDAL,Z

EXIT:

MOVF1,AL

MOVAH,4CH

INT21H

CODEENDS

ENDSTART

(2)跳转表法分支程序设计

1)分支地址表法

用分支地址表法实现分支程序设计的思想是:

将一系列的转移地址(即各分支处理子程序的首地址)存放在一段连续的存储区中,构成跳转表,采用间接转移指令来实现多分支转移。

【例2.57】设计多路分支程序,现有5个程序段,各程序段的首地址分别为P1,P2,P3,P4,P5,要求根据给定的参数转入相应的程序段。

分析:

根据题意,本题采用分支地址表法实现的多路分支结构程序设计,也是一种较常见的分支结构设计方法。

将5个程序段的入口地址作成表TABLE放入数据段,程序根据给定的参数计算出欲转入的程序段的首地址在TABLE中的位置后,取出该地址,跳转至该程序段。

由于表中按“字”存放数据,则每个数据的位移量是:

0、2、4、6、8。

对于给定参数N,计算位移量的公式是:

N=(N-1)*2。

编制程序如下:

例如:

TABLEDWP1,P2,P3,P4,P5;转移地址表

DATDB3;转移地址表

CHARlDB‘1’;结果显示字符

CHAR2DB‘2’

CHAR3DB‘3’

CHAR4DB‘4’

CHAR5DB‘5’

DATA1ENDS

STACKlSEGMENTPARASTACK

DW20DUP(0)

STACKlENDS

CODESEGMENT

ASSUMECS:

CODE,DS:

DATA1,SS:

STACKl

BEGIN:

MOVAX,DATA1

MOVDS,AX

MOVAL,DAT

MOVAH,00H

DECAL

SHLAL,1

LEABX,TABLE

ADDBX,AX

JMP[BX]

P1:

MOVDL,CHAR1

JMPP6

P2:

MOVDL,CHAR2

JMPP6

P3:

MOVDL,CHAR3

JMPP6

P4:

MOVDL,CHAR4

JMPP6

P5:

MOVDL,CHAR5

JMPP6

P5:

MOVDL,CHAR5

JMPP6

P6:

MOVAH,02H

INT21H

MOVAH,4CH

INT21H

CODEENDS

ENDBEGIN

运行后在屏幕上输出3,即运行了P3程序段。

该程序利用了分支地址表法设计程序的走向。

实际应用时,可以在各程序段中放入实际程序。

2)转移指令表法

转移指令表与上述的分支地址表法相比有两点区别:

其一,构成跳转表里不是n个分支程序入口处的偏移地址,而是转向n个分支程序的无条件转移指令:

JMPBRi

(i=0,1,2,3,……,n-1);其二,跳转表不是用DW或DD指令定义,而是作为代码段的一段程序,该跳转表的首址BASE不是变量而是标号。

当需要跳转到第i个分支时,只需将标号BASE的偏移地址与2*i之和送BX,然后使用指令:

JMPBX

即使程序转向

JMPBRi

进而转向BRi分支。

【例2.58】根据键盘输入数字0,1,2和3分别显示信息“8086/8088”,“80386”,“80486”,“Pentium”。

分析:

将4条无件短转移指令(该指令占2个字节)依次存放在基地址为BASE的跳转表中,这些指令的功能分别是转向显示信息“8086/8088”,“80386”,“80486”及“Pentium”的分支程序。

程序如下:

;…………数据段…………

DSEGSEGMENT

MESS0DB‘8086/8088’,’$’

MESS1DB‘80386’,’$’

MESS2DB‘80486’,’$’

MESS3DB‘Pentium’,’$’

DSEGENDS

;…………堆栈段…………

SSEGSEGMENT

DB80DUP(0)

SSEGENDS

;…………代码段…………

CSEGSEGMENT

ASSUMEDS:

DSEG,SS:

SSEG,CS:

CSEG

START:

MOVAX,DSEG

MOVDS,AX

MOVAH,01H

INT21H;从键盘输入’0’,’1’,’2’,’3’的ASCII码到AL

ANDAL,0FH;将输入’0’,’1’,’2’,’3’的转换为数字i

SHLAL,1;AX←2*i

CBW

MOVBX,OFFSETBASE

ADDBX,AX

JMPBX

BASE:

JMPSHORTM0

JMPSHORTM1

JMPSHORTM2

JMPSHORTM3

M0:

MOVDX,OFFSETMESS0

JMPDISP

M1:

MOVDX,OFFSETMESS1

JMPDISP

M2:

MOVDX,OFFSETMESS2

JMPDISP

M3:

MOVDX,OFFSETMESS3

DISP:

MOVAH,09H

INT21H

MOVAH,4CH

INT21H

CSEGENDS

ENDSTART

当需要实现超出短转移范围的近转移,或需要实现远转移时,跳转表中的指令就应该相应改为无条件近转移指令或无条件远转移指令,这两种指令分别占用3个字节和5个字节。

对于上例来说,应该对BX的内容的设置作相应的修改。

具体如何修改,请读者自己思考。

2.5.4循环结构程序设计

1.循环结构的组成

循环结构主要有三部分组成:

1)1) 初始化部分包括设置地址指针、计数器及其它变量的初值等为循环做的准备工作;

2)2) 循环体部分这是主要部分,即对问题的处理;

3)3) 循环控制部分包括每次执行循环体之后或之前参数的修改,对循环条件的判断等。

循环程序结构如图2.20所示,其中图2.18(a)是“先工作后控制”的结构,这种结构下,循环工作部分至少被执行一次;图2.18(b)是“先控制后工作”的结构,这种结构下允许“0”次循环。

2.循环的分类

按照“先判断”还是“先执行”,可以分成“当型循环”与“直到型循环”;按照循环条件,可以分成“循环次数已知”与“循环次数未知”。

汇编语言程序设计中更主要的是按照是否已知循环次数来区分,分别写成不同形式的程序代码。

另外,按照是否有循环嵌套,还可分成单重循环结构与多重循环结构。

3.单循环程序的设计方法

(1)“循环次数已知型”的程序设计

这种程序设计方法很直观、流程比较清晰,但必须在循环次数已知的的条件下才能采用。

【例2.59】在以NUM为首址的存区中存有n个带符号的字节类型的数据,从中找出最大数并送入MAX单元。

分析:

编程方法是首将先第1单元内容送AL中,然后将AL中内容与后面余下的n-1个数据进行比较,若AL中内容大于内存单元中内容,则保持AL中内容不变,否则将内存单元中内容送AL中。

最后AL中就为最大数并送MAX单元,程序流程图如图2.19所示。

程序如下:

;…………数据段…………

DATASEGMENT

NUMDB

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

当前位置:首页 > 高中教育 > 高中教育

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

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