《计算机原理与汇编语言程序设计》课件第5章_第1页
《计算机原理与汇编语言程序设计》课件第5章_第2页
《计算机原理与汇编语言程序设计》课件第5章_第3页
《计算机原理与汇编语言程序设计》课件第5章_第4页
《计算机原理与汇编语言程序设计》课件第5章_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章汇编语言5.1基本概念5.2汇编语言语句5.3汇编语言常用伪指令习题

5.1基本概念汇编语言是一种面向机器的程序设计语言,它采用助记符来表示机器指令的操作码和操作数,用符号地址表示操作数地址。汇编语言编写的源程序是不能在计算机上直接运行的,必须将其翻译成机器语言的目标程序后,计算机才能执行,这个翻译过程称为汇编,完成汇编任务的程序称为汇编程序。汇编程序是最早也是最成熟的一种系统软件,它除了能将汇编语言源程序翻译成机器语言程序外,还能够根据用户的要求分配程序区、数据区、暂存区等;能把各种进位制数转换成二进制数,把字符转换成ASCII码,计算表达式的值等;也能自动对源程序进行检查,给出如非法格式,未定义的助记符、标号,漏掉操作数等错误信息,具有这些功能的汇编程序称为基本汇编ASM(Assembler)。宏汇编MASM(MacroAssembler)是在基本汇编的功能上,增加了宏指令、结构、记录等高级汇编语言功能。汇编语言源程序由若干个语句组成,语句分为指令语句、伪指令语句和宏指令语句。

1.指令语句指令语句又称机器指令语句,是给CPU的命令,在运行时由CPU执行,每条指令对应CPU的一种特定的操作,例如数据传送、加、减运算等。指令语句是可执行语句。

2.伪指令语句伪指令语句也叫指示性语句,形式上与一般指令相似,但伪指令是给汇编程序的命令,它们不是在程序运行期间由计算机来执行的,而是在汇编过程中由汇编程序进行处理,伪指令只是为汇编程序提供有关信息,不产生相应的机器代码。例如定义数据、分配存储区、定义段及定义过程等。汇编以后,每条汇编指令都会产生与之对应的目标代码,而伪指令则不会产生相应的目标代码。

3.宏指令语句给一个需要重复使用的程序段命一个名,进行宏定义,该程序段就称为宏,以后需要使用这段程序时,只要在相应的位置上使用宏名,宏的引用语句就是宏指令语句。汇编时,汇编程序会把遇到的宏指令语句还原成原来的程序段,用这种方法可以提高编程效率。5.2汇编语言语句5.2.1汇编语言语句格式汇编语言的语句都是由四个域组成的,格式如下:

[名字项]操作码项[操作数项][;注释项]其中带方括号的项是可选项。

1.名字项不同的语句名字项有不同的名称和含义。指令语句或宏指令中的名字项称为标号,后面用冒号与操作码项作分隔。标号是指令的符号地址,可作为转移指令或子程序调用的目标地址。伪指令中的名字项可称为符号名,不同的伪指令其名字项的作用也不同,可以是变量名、符号常数名、子程序名或段名等。伪指令语句的名字项与操作码项是用空格分隔的。汇编程序对名字项有严格的规定。

(1)名字项可以使用下列字符:大/小写字母、数字、特殊字符 ?、_、@。名字项的第一个字符不能用数字,必须是字母或特殊字符,但“?”不能单独作名字项。名字项的最大长度不超过31个字符,如果超过则后继字符无效。

(2)名字项不能使用保留字。汇编语言中的CPU寄存器名、指令助记符、伪指令助记符或运算符等都属于保留字。

(3)名字项最好使用有意义的字符串。使用有明确意义的字符串作名字项,用户比较容易记忆,如用DATA表示数据,SUM表示累加和等。

(4)名字项在程序中不能重复定义。在同一个程序中,相同名字项的定义只允许出现一次,否则汇编程序会指示出错。

2.操作码项操作码用来指明操作的性质或功能,表示语句实现的具体操作,是四个域中唯一不可或缺的项。指令和伪指令中的助记符都是操作码。操作码项与操作数项之间用空格分开,MOV、ADD等都是操作码。

3.操作数项指令中的操作数项用来指定参与操作的数据。对于可执行指令可能有一个或两个操作数,也可能没有操作数;对于伪指令和宏指令,可以有多个操作数。当操作数多于一个时,操作数之间用逗号分开。操作数项可以是常数、变量、标号、寄存器、表达式等。

4.注释项注释是语句的说明部分,用来说明一条指令或一段程序的功能,用分号(;)与操作数分隔。在一些语句后适当地加些注释,可以增加程序的可读性,便于阅读、理解和修改程序。汇编源程序时,注释部分不产生机器代码。5.2.2操作数常见的操作数有寄存器、常数、变量、标号、表达式等。下面主要介绍后面四种操作数。

1.常数常数是没有属性的纯数,它的值在汇编时已完全确定,程序运行过程中不会发生变化。常数通常被称为立即数,它只能用作源操作数,不能作为目标操作数。它的位数由指令中的目标操作数决定,或为8位或为16位。常数分为以下几种:

1)数值常数汇编语言中的数值常数可以是二进制、八进制、十进制或十六进制数,书写时用数字加后缀(二进制用B、八进制用O或Q、十进制用D、十六进制用H)的方式区分不同进位制数。十进制数可以省掉后缀。对于十六进制数以A~F开头的数,数字前面要加0,避免和字符串混淆。

2)字符串常数字符串常数是由单引号括起来的一个或多个字符。字符串在计算机中存储的是相应字符的ASCII码。如 'A' 的值是41H,'ab' 的值是6162H等。也可以直接写ASCII码,ASCII码之间用逗号作分隔,此时就不要用单引号了。

3)符号常数符号常数是用符号定义伪指令定义的符号,这时可以用符号名代替常数或表达式的值。

2.变量变量是指存放在某些存储单元中的数据,这些数据在程序运行期间是可以改变的。变量名是操作数的符号地址。变量属于存储器操作数,经常出现在指令中,既可以作为源操作数,也可以作为目的操作数。变量有三种属性:段属性、偏移属性和类型属性。段属性:指变量所在段的段起始地址。偏移属性:指变量的偏移地址,是从段的起始地址到变量所在位置之间的字节数。类型属性:指变量占用存储单元的字节数,有Byte(字节)、Word(字)、DWord(双字)等几种。变量的段属性和偏移属性构成了变量的逻辑地址。

3.标号标号出现在代码段中,是机器指令的符号地址,指示汇编后指令代码在存储器中的位置。标号也属于存储器操作数,也有三种属性:段属性、偏移属性和类型属性。段属性:指标号所在段的段起始地址。偏移属性:指标号在段内的偏移地址,是从段起始地址到标号所在位置之间的字节数。类型属性:指该标号是在段内引用还是在段间引用的。若是段内引用的,则为NEAR;若是段间引用的,则为FAR。标号的段属性和偏移属性构成了标号的逻辑地址。

4.表达式由常数、变量、标号通过操作运算符连接而成的式子称为表达式,是操作数的基本形式。表达式的值是在程序汇编过程中计算确定的,不是在程序运行时获得的。表达式有数值表达式和地址表达式两种。数值表达式是由算术运算符、数值返回运算符等连接而成的式子,它的运算结果是一个数值常数,只有大小,没有属性。地址表达式是由变量、常数、标号、寄存器名和操作符连接而成的式子,它的运算结果是一个存储单元的地址。5.2.3运算符

8086汇编语言中常用的运算操作符有算术运算符、逻辑运算符、关系运算符、数值返回运算符、属性修改运算符等。下面重点介绍算术运算符、数值返回运算符和属性修改运算符。

1.算术运算符算术运算符包括加(+)、减(-)、乘(*)、除(/)和MOD。MOD运算符进行的是整除,得到的是余数部分。例如,39MOD6,其结果为3。当算术运算符运用于地址表达式时,应保证其结果有明确的物理意义,使用比较多的是“+”和“-”运算。例如:要将首地址为BUF的字节数组中的第5个数送至AL单元,实现的指令如下:

MOVAL,BUF+4

2.数值返回运算符数值返回运算符用来把存储器操作数(变量或标号)分解为它的组成部分,并且返回一个表示结果的数值。这组运算符有5个,分别是:

1) SEG运算符格式:SEG变量名或标号返回的是变量或标号所在段的段基值。例如:MOVBX,SEGDATA如果变量DATA所在段的段基值为2300H,这条指令的结果就是:BX = 2300H。

2) OFFSET运算符格式:OFFSET变量名或标号返回的是变量或标号的段内偏移量。例如:MOVSI,OFFSETDATA设DATA在段内的偏移量是421H,这条指令的结果是:SI=0421H。这条指令与指令

LEASI,DATA是等效的。

3) TYPE运算符格式:TYPE变量名或标号返回的是变量或标号的类型数值。如果是变量,返回的数值是变量所占的字节数:DB为1,DW为2,DD为4,DQ为8,DT为10;如果是标号,则返回的是代表标号类型的数值:NEAR为-1,FAR为-2,这个数据没有什么实际的意义。

4) LENGTH运算符格式:LENGTH变量返回的是数组变量的元素个数。如果变量中使用了DUP表达式,则返回的是最外层DUP的值;如果没有使用DUP表达式,则返回的值是1。

5) SIZE运算符格式:SIZE变量返回的是数组变量所占的总字节数,也就是等于LENGTH和TYPE两个运算符返回值的乘积。例如:变量BUFFER定义为36个“1”,变量的类型是字,用伪指令定义为

BUFFERDW36DUP(1)

则指令

MOVDX,SIZEBUFFER的结果为DX=72。

3.属性修改运算符格式:类型PTR表达式其中:类型可以是BYTE、WORD、DWORD和NEAR、FAR。运算结果是将表达式所指定的变量、标号或存储器操作数的类型属性,临时性地修改或指定为PTR运算中规定的类型。这种修改是临时性的,仅在有修改运算符的语句内有效。例如:要将一个字变量WDA中高字节的内容送AH,指令为

MOVAH,BYTEPTRWDA+15.3汇编语言常用伪指令5.3.1数据定义伪指令数据定义伪指令用来定义一个变量的类型,并为变量分配存储单元及预置初值,也可以只给变量分配存储单元,而不赋初值。数据定义伪指令的一般格式为其中:DB用来定义字节数据,每个操作数一个字节;DW用来定义字数据,每个操作数16位,两个字节(低字节在低地址中,高字节在高地址中);DD用来定义双字数据,每个操作数32位。数据定义伪指令还有DF和DQ等形式,分别用来定义6个字节数和4字数,但比较少见,所以就不介绍了。数据定义伪指令的操作数可以是常数、表达式或字符串,但每项操作数的值不能超过由伪指令所定义的数据类型限定的范围。例如,DB伪指令定义的是字节类型数据,数的范围应该是0~255(无符号数)和-128~+127(带符号数)。

1.操作数的种类

1)操作数是常数或数值表达式

DA_B DB 10101010B,10,10H

DA_W DW4*64,100H,400Q

DA_D DD 0E74DH,-20汇编程序在汇编期间根据上述定义的变量类型在存储器内分配存储单元,汇编后的内存分布如图5-1所示。图5-1操作数是常数

2)操作数是字符串字符串是由单引号括起来的一串字符。如果用DB伪指令定义,字符串的长度不能超过255个,汇编时为每个字符分配一个存储单元,自左向右以字符的ASCII码形式按地址递增的顺序存入。如果用DW伪指令定义,每个数据只能是两个字符,汇编时前一个字符的ASCII码作高字节,后一个字符为低字节。

STR1DB'2591H','CD'

STR2DW'CD',10H

STR3DD'CD'汇编后的内存情况如图5-2所示。图5-2操作数是字符串

3)操作数是带 ? 的表达式不带引号的 ? 表示预留空间。

DA_B DB50,?,?,0A5H

DA_W DW?,43H

汇编后的结果见图5-3。

4)操作数是带DUP的表达式

DUP是定义重复数据操作符。格式:表达式1DUP(表达式2)其中:表达式1是重复次数,表达式2是重复的内容。如果待操作的数据中有一组相同的数据要进行定义,这时用DUP就很方便。例如:

ARY1DB20HDUP(1),2DUP(0,1,2,?)

ARY2DW8DUP(?)汇编后的结果见图5-4。

DUP可以嵌套使用,例如:

ARY3DW 5DUP(2DUP(9,3))

ARY4DB 10HDUP(1,2DUP(3,4),5,6)汇编后的结果见图5-5。图5-3带?的表达式图5-4DUP操作符图5-5DUP嵌套

5)操作数是地址表达式可以用DW或DD伪指令把变量或标号的偏移地址或由16位段地址和16位偏移地址组成的整个地址存入存储器。用DD伪指令存入地址时,第1个字为偏移地址,第2个字为段地址。例如(见图5-2),伪指令

ADR1DWSTR1

ADR2DDSTR3汇编后,内存的内容如图5-6所示。图5-6操作数是地址表达式

2.变量的使用用数据定义伪指令定义过的变量有指定的类型,在程序中使用这些变量时必须严格按定义的类型工作。例如,有以下的数据定义:

DATA1DB 35H,46H

DATA2DW 7812H指令:

MOVAH,DATA1+1

MOVBX,DATA2是正确的。而

MOVAX,DATA1

MOVBL,DATA2则是错误的。如果要从定义为字节或字的变量中获得不同类型的数,则可以使用PTR运算符。例如:

MOVAX,WORDPTRDATA1

MOVBL,BYTEPTRDATA2指令执行后的结果分别为

AX=4635H

BL=12H5.3.2符号定义伪指令符号定义伪指令的作用是给一个符号命名,或定义新的类型属性等。这些符号可以包括汇编语言的变量名、标号名、过程名、寄存器名以及指令助记符等。

1. EQU伪指令

格式:符号名EQU表达式功能:用符号名来代替给定的表达式,之后程序中凡用到该表达式的地方,都可以用符号名来代替。格式中的表达式可以是操作数的地址、常数表达式,甚至可以是助记符。需要注意的是,一个符号经EQU伪指令定义后,在同一个程序中,不允许再对这个符号重新赋值。例如:

CON EQU156 ;CON被赋值为156

BETA EQUCON-42 ;BETA被赋值为156-42(=114)

DATA EQUARY+BETA ;DATA与ARY+114等价

A EQUADD ;用A代替指令ADD

SC EQUCS:[BP+3] ;带段超越的地址表达式用符号名SC代替

2.“=”伪指令格式:符号名=表达式“=”伪指令与EQU伪指令类似,也用于给操作数赋初值,它们之间的区别是:EQU伪指令中的符号名不允许重复定义,而“=”伪指令则允许重复定义。例如:

NUM=13*5 ;NUM=65

NUM=NUM/6 ;NUM=10

NUM=NUM-7 ;NUM=3

NUM=NUM+3 ;NUM=6

NUM=NUMMOD5;NUM=1

ORG3460H ;下列数据的偏移地址从3460H开始

BUF1DW'45',960CH

BUF2DB3DUP('ABCD')

DATA=BUF2+4 ;DATA=3468H

CON=BUF2-BUF1 ;CON=4但

COUNT EQU 25

COUNT EQUCOUNT+1是错误的,正确的用法应该是:

COUNT EQU 25

COUNT1 EQUCOUNT+1用EQU定义过的符号名来代替指令或地址时,必须先定义才能使用,否则极容易造成混乱。5.3.3段定义伪指令

8086CPU是按段来使用存储器的,所以编写一个汇编语言的源程序时,也必须按段来构造程序。汇编程序把源程序转换为目标程序时,要有标号和变量的偏移地址,并将有关信息通过目标模块传送给连接程序,连接程序才能把不同的段和模块连接在一起,形成一个可执行的程序。段定义伪指令就是对段进行定义。汇编语言程序的逻辑段有代码段、数据段、堆栈段和附加段,它们的作用如下:代码段:程序代码存储区。数据段:程序的数据存储区,定义程序要用的操作数,指令通过变量来引用这些数据。堆栈段:为程序堆栈定义一块存储区,大小由用户定义,最大不超过64KB。附加段:附加的数据存储区,串操作时,字符串的目的地址必须放在附加段。在一个程序中不一定4个段都设置,但至少要定义一个代码段。

1.段定义伪指令在汇编语言程序中定义逻辑段,用它来指定段的名称和范围,并指明段的定位类型、组合类型及类别。其格式如下:段名SEGMENT[定位类型][组合类型][类别名]

段名ENDS

SEGMENT和ENDS要成对使用,段名由用户自定义,一般建议选用与本段用途相关的字母组合,一个段开始和结束使用的段名要一致。对于数据段、附加段和堆栈段来说,删节号部分一般是数据定义和符号定义等伪指令,对于代码段则既有指令又有伪指令。一般情况下,SEGMENT后面的说明可以不用。但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要使用这些说明。

1)定位类型(ALIGN_TYPE)定位类型表示对该段起始边界的要求,可有4种选择:

(1) PARA:指定段的起始地址必须从某一个节的边界开始(1节等于16个字节),即段起始地址最低位为0。

(2) PAGE:表示本段起始地址必须从存储器的某一个页的边界开始(1页等于256个字节)。即段起始地址的最低两个十六进制数位必须为0。

(3) WORD:表示本段必须从字的边界开始,即段起始地址是偶数。

(4) BYTE:表示本段可以从任何地址开始。定位类型的默认项是PARA,即如果省略定位类型,则汇编程序默认为PARA。

2)组合类型(COMBINE_TYPE)组合类型指定段与段之间的连接和定位方式。有6种组合类型可供选择:

(1) NONE类型:表示该段与其他段在逻辑上不发生连接关系,这是隐含的组合类型,若省略“组合类型”项,即为NONE。

(2) PUBLIC类型:连接时,在满足定位类型的前提下,不同模块中属于该类型的同名同类别的段邻接在一起,组成一个物理段,使用同一段基址。该段的总长度不能超过64KB。

(3) STACK类型:与PUBLIC类型同样处理,只是组合后的该段用作堆栈。当段定义中指明了STACK类型后,说明堆栈已经确定,系统会把这个连续段的首地址赋值给堆栈段寄存器SS,并初始化堆栈指针SP。

(4) COMMON类型:连接时,将不同模块中属于该类型的同名同类别的各段连接成一段,它们共用一个基地址,产生覆盖段。连接后,段的长度由最长的COMMON段决定。

(5) AT表达式类型:表示本段可定位在表达式所指示的节边界上。如“AT3090H”,表明本段从绝对地址30900H开始。但是,它不能用来指定代码段。

(6) MEMORY类型:连接时,本段定位在其他所有段的最高地址端。若有几个段同时选择MEMORY类型,则汇编程序只把所遇到的第一个段作MEMORY组合类型处理,其他段作为COMMON类型。

3)类别名(CLASS)类别名是表示段的类别,由用户任选字符串组成。类别名必须用单引号括起来。在连接时,连接程序会将各个程序模块中具有同样类别名的逻辑段按先后顺序放在一个连续的存储区中,每段各有自己的段首址。类别名说明并不能把相同类别的段合并成一个段,但在连接后形成的装入模块中,可以把它们的位置靠在一起。例如,有以下几个段的定义:

DATA1 SEGMENT'DATA‘

DATA1 ENDS

CODE SEGMENT'CODE‘

CODE ENDS

STACK1 SEGMENT'STACK‘

STACK1 ENDS

DATA2 SEGMENT'DATA‘

DATA2 ENDS

STACK2 SEGMENT'STACK‘

STACK2 ENDS经连接程序连接后,各段的位置如下:

DATA1 SEGMENT'DATA‘

DATA1 ENDS

DATA2 SEGMENT'DATA‘

DATA2 ENDS

STACK1 SEGMENT'STACK‘

STACK1 ENDS

STACK2 SEGMENT'STACK‘

STACK2 ENDS

CODE SEGMENT‘CODE’;代码段位于程序的高地址区

CODE ENDS

2.段指定伪指令在进行了段定义后,还必须说明段和段寄存器的关系,这要用段指定伪指令来实现,其格式为:

ASSUME段寄存器名:段名[,段寄存器名:段名,…]其中,“段寄存器名”必须是CS、DS、ES和SS中的一个,而“段名”则必须是由SEGMENT定义过的段名。用ASSUME语句不一定要设置全部4个段寄存器,可以定义几个段就设置几个。例如,一个较为完整的汇编源程序段定义如下:

DATE_SEG1 SEGMENT ;定义数据段

DATE_SEG1 ENDS

DATA_SEG2 SEGMENT ;定义数据附加段

DATA_SEG2 ENDS

CODE_SEG SEGMENT ;定义代码段

ASSUMECS:CODE_SEG,DS:DATA_SEG1,ES:DATA_SEG2

START: MOV AX,DATA_SEG1 ;程序的入口地址

MOV DS,AX ;设置DS,给DS赋初值

MOV AX,DATA_SEG2

MOV ES,AX ;ES赋初值

CODE_SEG ENDS ;代码段定义结束

END START ;源程序结束上述例子只设置了3个段寄存器。如果要取消已经由ASSUME所指定的段寄存器和段名的对应关系,可以用

ASSUMENOTHIN删除全部段寄存器的设置。而用

ASSUME段寄存器:NOTHIN删除指定的段寄存器与某段的关联。

3.段初值的装填

ASSUME伪指令只是指定了段与段寄存器的对应关系,并没有把相应的段地址装入段寄存器中,将段地址装入段寄存器的工作是由代码段中的指令来实现的。4个段寄存器的装入方法不完全相同。

1) DS与ES的装填可以通过给段寄存器赋初值实现DS与ES的装填。上例中,指令

MOV AX,DATA_SEG1

MOV DS,AX

MOV AX,DATA_SEG2

MOV ES,AX 分别将数据段、附加段的首地址DATA_SEG1和DATA_SEG2装入DS、ES中。

2) SS的装填

SS装填的方法有两种:

(1)定义堆栈段时,在组合类型中选择“STACK”参数,并且在段定义伪指令语句中把这个段指派给SS。例如:

STSEG SEGMENTSTACK ;定义一个堆栈段,组合类型“STACK”不能省略

DB64DUP(?) ;定义堆栈区,预留了64个字节用于堆栈

STSEG ENDS ;段定义结束

CDSEG SEGMENT

ASSUMECS:CDSEG,SS:STSEG

(2)如果在段定义伪指令的组合类型中没有选“STACK”参数,这时可以用类似于DS,ES的装填办法,用几条指令来设置SS和SP的初值。例如:

STSEG SEGMENTSTACK ;定义一个堆栈段,组合类型“STACK”不能省略

DB64DUP(?) ;定义堆栈区,预留了64个字节用于堆栈

TOP LABELWORD

STSEG ENDS ;段定义结束

CDSEG SEGMENT

ASSUMECS:CDSEG,SS:STSEG

MOV AX,STSEG

MOV SS,AX

MOV SP,OFFSETTOP

3) CS的装填为了保证程序的正确执行,CS和IP的值要同时设置,但CS提供的是正在执行程序的段首址,IP提供的是将要执行指令的偏移地址,这两部分都不能由用户指定,而要根据目标程序在存储器中的存储位置来决定,所以CS和IP的装填不是通过执行指令实现的,而是通过确定源程序的开始和结束,由系统自动装填的。下面是一个完整的源程序:

DSEG SEGMENT ;数据段名DTSEG

DATA1 DB36H

DATA2 DB4BH

SUM DB?

DSEG ENDS

SSEG SEGMENTSTACK;堆栈段名SSEG,组合类型“STACK”不能省略

DW100DUP(?)

SSEG ENDS

CSEG SEGMENT;代码段名CSEG

ASSUMECS:CSEG,DS:DSEG,ES:DSEG,SS:SSEG;DS与ES完全重叠

START: MOV AX,DSEG;程序的入口地址

MOV DS,AX;数据段寄存器装填

MOV AX,DSEG MOV ES,AX;附加段寄存器装填

MOV AL,DATA1 MOV BL,DATA2 ADD AL,BL MOV SUM,AL MOV AH,4CH INT 21H;程序结束,返回DOS

CSEG ENDS;代码段定义结束

END START;汇编全部结束,系统给CS、IP赋值5.3.4结束伪指令每一个源程序都必须用结束伪指令来表示结束。结束伪指令的格式为:

END[LABEL]其中,LABEL是程序开始执行的起始地址,也就是主模块(主程序或主过程所在的模块)第一条指令的标号。如果多个程序模块相连接,则只有主模块的起始地址要使用标号,因此也只有主模块中的END伪指令必须带有LABEL选项,其他模块中的END伪指令不带LABEL选项。汇编程序在遇到END时结束汇编,程序将从主模块的第一个标号处开始执行。

【例5-1】在给定的数据段中,分析数据定义伪指令的使用和存储单元的初始化。

DATASEGMENT;定义数据段

B1DB10H,30H;B1为字节变量,存入10H和30H

B2DB2﹡3+5 ;B2存入表达式的值0BH

S1DB'GOOD!' ;从S1开始存入'GOOD!'的ASCII码

W1DW1000H,2030H ;从W1开始存入两个字数1000H和2030H

W2EQU47 ;定义W2=47

S2DB'AB';按字节存入字符'AB'的ASCII码

S3DW'AB';按字存入字符'AB'的ASCII码

DATAENDS;数据段结束5.3.5当前地址计数器($)与定位伪指令

1.当前地址计数器($)地址指针是记录当前地址的计数器。在汇编程序对源程序汇编的过程中,使用当前地址计数器(LocationCounter)来保存当前正在汇编的指令的偏移地址。当开始汇编或在每一段开始时,地址计数器初始化为零,在以后的汇编过程中,每处理一条指令,计数器就自动增加,增加的量为该指令所需要的字节数。地址指针的值可用$来表示,汇编语言允许用户直接用$来引用当前地址计数器的值,因此指令:

JNE$+6的转向地址是JNE指令的地址加上6。当$用在指令中时,它表示该指令的第一个字节的地址。这里,$+6必须是另一条指令的地址。否则,汇编程序将指示出错信息。当$用在伪指令的参数字段时,则和它用在指令中的情况不同,它所表示的是地址计数器的当前值。

【例5-2】有变量定义伪指令:

BUF DW 4,3,$+6,7,$+6如果汇编时BUF分配的偏移地址为0312H,则汇编后的存储区如图5-7所示。注意:BUF数组中的两个$+6得到的结果是不同的,这是由于$的值是不断变化的,第一次的$为0316H,第二次的$为031AH。图5-7$的用法

2.定位伪指令格式:ORG地址表达式功能:用来指定数据段的起始偏移地址或代码段的起始偏移地址,亦即用来设置当前地址指针的初值。例如:

ORG100H

0100HDATA1DB100 ;DATA1=0100H

ORG200H

START:  MOVAX,BX ;START=0200H

…地址表达式也可以表示从已定义过的地址开始的位移量,或表示从当前地址计数器值$开始的位移量。例如:

ORG$+16可以表示跳过16个字节的存储区,等同于预留了16字节的未赋初值的数据区。相当于执行伪指令:

DB 16DUP(?)5.3.6过程定义伪指令过程是具有独立功能的程序段。在程序设计中,经常将一些重复出现的语句组定义为子程序,又称为过程,供其他程序调用。格式:过程名 PROC[NEAR]/FAR

RET

…过程名 ENDP在程序设计过程中,有时为了使程序的结构更清晰,一个代码段通常由几个过程组成。过程有两个属性:FAR/NEAR,默认为NEAR。当用CALL指令对过程进行调用时,段内调用就是NEAR,段间调用就是FAR。习题

1.下列作为名字项的符号,哪些是合法的?哪些是非法的?为什么?

GAME,DW,ASSUME,CX,AC9H,?,A*B,B9,DA_6,7DH,BUF,$F6,LOOP

2.假设下列指令中的所有标识符均是类型属性为字的变量,请指出下列指令中哪些是非法的,它们的错误是什么?

(1) MOVBP,AL

(2) MOVWORD_OP[BX+4*3][DI],SP

(3) MOVWORD_OP1,WORD_OP2

(4) MOVAX,WORD_OP1[DX]

(5) MOVSAVEWORD,DS

(6) MOVSP,SS:DATA_WORD[BX][SI]

(7) MOV[BX][SI],2

(8) MOVAX,WORD_OP1+WORD_OP2

(9) MOVAX,WORD_OP1-WORD_OP2+100

(10) MOVWORD_OP1,WORD_OP1-WORD_OP2

3.假设VAR1和VAR2为字变量,LAB为标号,试指出下列指令的错误之处。

(1)

ADD VAR1,VAR2

(2)

SUB AL,VAR1

(3)

JMP LAB[SI]

(4) JNZ VAR1

(5) JMP NEARLAB

4.画图说明下列语句所分配的存储空间和初始化的数据值。

(1) BYTE_VARDB'BYTE',12,-12H,3DUP(0,?,2DUP(1,2),?)

(2) WORD_VARDW5DUP(0,1,2),?,-5,,'BY','TE',256H

5.试列举出使汇编程序把5150H存入一个存储器字中(例如,DW5150H)的各种方法。

6.请设置一个数据段DATASG,并定义以下字符变量或数据变量。

(1)

FLD1B为字符串变量:'PERSONALCOMPUTER'。

(2)

FLD2B为十进制数字节变量:32。

(3)

FLD3B为十六进制数字节变量:20。

(4)

FLD4B为二进制数字节变量:01011001。

(5)

FLD5B为数字的ASCII字符字节变量:32654。

(6)

FLD6B为10个零的字节变量。

(7)

FLD7B为零件名(ASCII码)和其数量(十进制数)的表格:

PART120

PART250

PART314

(8) FLD1W为十六进制数字变量:FFF0。

(9) FLD2W为二进制数字变量:01011001B。

(10) FLD3W为(7)中零件表的地址变量。

(11)

FLD4W为包括5个十进制数的字变量:5,6,7,8,9。

(12)

FLD5W为5个零的字变量。

(13)

FLD6W为本段中字数据变量和字节数据变量之间的地址差。

7.假设程序中的数据定义如下:

PARTNO DW?

PNAME DB16DUP(?)

COUNT DD?

PLENTH EQU$-PARTNO则PLENTH的值为多少?它表示什么意义?

8.有符号定义语句如下:

BUFF DB1,2,3,'123'

EBUFF DB0

L EQUEBUFF_BUFF则L的值是多少?

9.假设程序中的数据定义如下:

LNAME DB 30DUP(?)

ADDRESS DB 30DUP(?)

CITY DB 15DUP(?)

CODE_LIST DB 1,7,8,3,2

(1)用一条MOV指令将LNAME的偏移地址放入AX。

(2)用一条指令将CODE_LIST的头两个字节的内容放入SI。

(3)写一条伪指令使CODE_LENGHT的值等于CODE_LIST域的实际长度。

10.试写出一个完整的数据段DATA_SEG,它把整数5赋予一个字节,并把整数1,0,2,5和4放在10字数组DATA_LIST的头5个单元中。然后,写出完整的代码段,其功能为:把DATA_LIST中头5个数中的最大值和最小值分别存入MAX和MIN单元中。

11.给出等值语句如下:

ALPHA EQU 100

BETA EQU 25

GAMMA EQU 2下列表达式的值是多少?

(1) ALPHA*100+BETA

(2) ALPHA MOD GAMMA+BETA

(3) (ALPHA+2)*BETA?2

(4) (BETA/3)MOD5

(5) (ALPHA+3)*(BETAMODGAMMA)

(6) ALPHAGEGAMMA

(7) BETAAND7

(8)

GAMMAOR3

12.对于下面的数据定义,3条MOV指令分别汇编成什么(可用立即数方式表示)?

TABLEA DW 10DUP(?)

TABLEB DB 10DUP(?)

ABLEC DB '1234'

MOV AX,LENGTHTABLEA

MOV BL,LENGTHTABLEB

MOV CL,LENGTHTABLEC

13.对于下面的数据定义,各条MOV指令单独执行后,有关寄存器的内容是什么?

FLDB DB ?

TABLEA DW 20 DUP(?)

TABLEB DB 'ABCD'

(1)

MOVAX,TYPEFLDB

(2)

MOVAX,TYPETABLEA

(3)

MOVCX,LENGTH TABL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论