汇编语言的基础知识标识符和表达式的--复合内存变量的定义【4】

转载自:http://blog.csdn.net/shadet/article/details/447743

4 复合内存变量的定义

上节,我们介绍了汇编语言中六个最基本的数据类型,这些数据类型能满足程序设计中绝大多数情况的需要,但也存在需要更复杂的数据类型的情况。

下面介绍汇编语言所提供的三种复合数据类型的说明形式。

4.1 重复说明符DUP

从前面的内容里,我们知道了定义少量内存变量的定义形式,但如果在程序中要说明50个、100个、200个甚至更多的、同类型的内存变量时,若采用前面所学的方法,对它们一一加以说明显然是不可行的。为此,汇编语言提供了变量的重复说明符DUP,其说明的一般形式如下:

count  DUP  (表达式, 表达式, …, 表达式)

解释:count是重复次数,(表达式, 表达式, …, 表达式)是被重复的部分,“表达式”可以是存储单元的初值,也可以是含义另一个DUP的式子。如果在表达式的括号中有多个表达式,那么,它们之间要用逗号','分开。

例如:

BUFFERDB100 DUP(?)
STRINGDB120 DUP('ABCDE'), 0
DATA1DW50 DUP(10H, 20 DUP(1,2,3), 20H)
POINTSDD12, 30 DUP(0)

从上面的例子可看出:用DUP说明内存变量相当于在高级语言中定义数组。

4.2 结构类型的定义

重复说明符DUP只能用于重复同一数据类型的变量说明,它不可以重复不同数据类型的变量说明。为了把一组不同类型的变量说明组合在一起,汇编语言提供了另一种复合数据类型说明符——结构类型说明符STRUC

1、结构类型的定义

STRUCENDS可以把一系列数据定义语句括起来作为一种新的、用户定义的结构类型。其一般说明格式如下:

结构名 STRUC [Alignment][, NONUNIQUE]

数据定义语句序列

结构名 ENDS

解释:结构名是一个合法的标识符,且具有唯一性。结构名代表整个结构类型,前后两个结构名必须一致。结构内被定义的变量为结构字段,变量名即为字段名。

一个结构中允许含有任意多个字段,各字段的类型和所占字节数也都可任意。如果字段有字段名,则字段名必须唯一。每个字段可独立存取。

  、对齐方式(Alignment):可用1、2或4来指定结构中字段的字节边界(Byte boundary),其缺省值为1。见有关叙述;

  、NONUNIQUE:要求结构中的字段必须用全名才能访问,见本小节中的“结构类型字段的引用”。

例如:

COURSE

STRUC在左上例中,COURSE是结构名,它含有三个字段:NO、CNAME和SCORE,它们的类型分别是DD、DB和DW。
NODD ?
CNAMEDB 'Assember'
SCOREDW 0

COURSE

ENDS

上例中,COURSE是结构名,它含有三个字段:NO、CNAME和SCORE,这些字段的类型分别是DD、DB和DW。结构COURSE的字段分布如图7所示。

    Assember  
NOCNAMESCORE

图7 结构类型COURSE的字段分布示意图

从图4.7,我们不难看出:结构类型COURSE共占14个字节,其字段NO、CNAME和SCORE的偏移量分别为:0、4和12。

结构中的字段可以有字段名,也可以没有字段名。有字段名的字段可直接用该字段名来访问它,没有字段名的字段可以用该字段在结构中的偏移量来访问。

例如:

PEASON

STRUC
NODD ? ;偏移量为0
NAMEDB 10 dup (?);偏移量为4
DB 1;偏移量为14

PEASOM

ENDS

在结构PEASON中,有二个字段有字段名,一个字段没有字段名,但不管有无字段名,我们都可用其偏移量来访问它。

2、结构类型变量的定义

在定义某个结构类型后,程序员就可以说明该结构类型的内存变量。它的说明形式与前面介绍的简单数据类型的变量说明基本上一致。其定义格式如下:

[变量名] 结构名 <[字段值表]>

解释:1)、

变量名即为该结构类型的变量名,它可省缺。如果省缺,则不能用符号名来访问该内存单元;
2)、字段值表是给字段赋初值,中间用逗号','分开,其字段值的排列顺序及类型应与该结构说明时各字段相一致;
3)、如果结构变量中某字段用其说明时的缺省值,那么,可用逗号来表示;如果所有字段都如此,则可省去字段值表,但必须保留一对尖括号"<"、">"。

例如:

COURSE1

COURSE <>;使用缺省的初值
COURSE2COURSE <1, 'Pascal', 60>
COURSE3COURSE <2, , 84> ;使用缺省的课程名
PEASON1PEASON<1000, '张 三', 34>

3、结构类型字段的引用

定义了结构类型的变量后,若要访问其结构中的某个字段,则可采用如下形式:

结构变量名.字段名

该引用方式与高级语言的字段引用方式完全一致,我们还可用偏移量来访问其中的某个字段,但此方法不直观,变动性大,所以,一般情况下,不提倡使用此方法。

例如:

 EXAM1STRUC
F1DW  ?
F2DB   ?
EVEN;偶对齐
F3DW  ?
EXAM1ENDS
E1EXAM1  <1234H,'A',8765H>;定义结构EXAM1的一个变量E1

下面二种方法都可以把结构变量E1中字段的内容赋给寄存器AX,但如果在字段F3之前增加或减少了字段,那么,这些引用需要改变吗?

(1)、用字段名直接引用

MOV AX, E1.F3

(2)、用字段的偏移量间接引用

LEA SI, E1
MOV AX, [SI+4]     ;其中4是字段F3的偏移量

4.3 联合类型的定义

联合数据类型是一种特殊的数据类型。它可以实现:以一种数据类型存储数据,以另一种数据类型来读取数据。程序员可以根据不同的需要,以不同的数据类型来读取联合类型中的数据。也就是说,在一些情况下,以一种数据类型来读取联合类型中的数据,而在另一些情况下,又以另一种数据类型来读取其数据。

1、联合类型的说明

联合数据类型其说明格式如下:

[联合类型名] UNION  [Alignment] [,NONUNIQUE]

数据定义语句序列

[联合类型名] ENDS

联合类型中的各字段相互覆盖,即同样的存储单元被多个不同的字段所对应,并且其每个字段的偏移量都为0。

联合类型所占的字节数是其所有字段所占字节数的最大值。

、对齐方式(Alignment):可用1、2或4来指定结构字节的边界,其缺省值为1。它还用可伪指令ALIGN或EVEN来重新定界,也可用命令行选项/Zp来定界;

、NONUNIQUE:要求联合类型中的字段必须用全名才能访问,引用联合类型字段的方法见下面的“联合类型字段的引用”。

例如:

 DATATYPEUNION
  BB DB ? ;定义一个字节类型的字段
  WW DW ? ;定义一个字类型的字段
  DD DD ? ;定义一个双字类型的字段
 DATATYPEENDS

联合类型DATATYPE的字段分布如图8所示。

在联合类型的最外层定义中,在伪指令UNION和ENDS的前面一定要书写该联合类型名,而在其嵌套定义的内层,伪指令UNION和ENDS之前一定不能写联合类型名。

图8 DATATYPE的字段分布示意图

例如:

 UNION1UNION
BBDB ?
WWDW ?
UNION;联合类型的嵌套定义形式
W1DW ?
B1DB ? 
ENDS
UNION1ENDS

2、联合类型变量的定义

联合数据类型的变量只能用第一个字段的数据类型来进行初始化。

例如:

 U1DATATYPE<'J'>  ;定义一个联合变量,并初始化其值
U2DATATYPE<1234H>;初始化错误,只能用字节数据来初始化
U3 UNION1<1>

3、联合类型字段的引用

定义了联合类型的变量后,就可根据需要,以不同的数据类型或字段名来存取该联合类型中的数据。引用其字段的具体形式如下:

联合类型变量名.字段名

例如:

 MOVU1.WW, 1234H;给联合类型变量赋字数据
 MOVAL, U1.BB;AL=34H
 MOVBX, U1.WW;BX=1234H
 MOVU1.BB, 'A';U1的值1241H,41H是'A'的ASCII码

4.4 记录类型的定义

1、记录类型的说明

汇编语言的记录类型与高级语言的记录类型不同,它是为按二进制位存取数据提供方便的。记录类型的说明要用到另一个保留字RECORD,其说明格式如下:

记录名 RECORD 字段 [, 字段, ……]

其中“字段”代表:字段名:宽度[=初值表达式]

解释:

1、记录名代表该记录类型;
2、记录类型可以由多个字段组成,每个字段之间要用逗号','分开;
3、字段的属性包括字段名、宽度和初值;

4、字段的“宽度”表示该字段所占的二进制位数,它必须是一个常数,并且所有字段的宽度之和不能大于16;如果记录的总宽度大于8,则系统为该记录类型分配二个字节,否则,只分配一个字节;
记录的最后一个字段排在所分配空间的最低位,然后对记录中的字段依次“从右向左”分配二进制位,左边没有分完的二进制位补0;

5、初值表达式给出的是该字段的缺省值。如果初值超过了该字段的表示范围,那么,在汇编时将产生错误提示信息;如果某字段没有初值表达式,则其初值为0。

例如:

 COLORRECORD BLINK:1, BACK:3=0, INTENSE:1=1, FORE:3
FLOATRECORD DSIGN:1, DATA:8, ESIGN:1, EXP:4

记录类型COLOR有四个字段:BLINK、BACK、INTENSE和FORE,它们的宽度分别为:1、3、1和3,所以,该记录类型共有8位二进制,系统分配给它一个字节。

记录类型COLOR的二进制位分布如右图9所示。

图9 记录类型COLOR的二进制位分配示意图

记录类型FLOAT用来模仿《计算机原理》中的浮点数表示法,它也有四个字段:

DSIGN (尾数的符号位);
DATA (尾数);
ESIGN (指数的符号位);
EXP (指数)。

图10 记录类型FLOAT的二进制位分配示意图

它们的总宽度是14,所以,系统要给它分配二个字节。记录类型FLOAT的二进制位分布如右图10所示。

2、记录变量的定义

在程序中,必须先说明记录类型,然后才能定义该记录类型的变量。记录变量是把其二进制位分成一个或多个字段的字节或字变量。其定义格式与其它类型变量的定义方式类似,具体如下:

[变量名]  记录名 <[字段值表]>

解释:

1、变量名即为该记录类型的变量名,它可省缺。如果省缺,则不能用符号名来访问该内存单元;

2、字段值表是给字段赋初值,中间用逗号','分开,其字段值的排列顺序及大小应与该记录说明时各字段相一致;

3、如果记录变量的某字段用其说明时的缺省值,那么,可用逗号来表示;如果所有字段都如此,则可省去字段值表,但必须保留一对尖括号"<"、">"。

例如:

 COLOR1COLOR <>, <1, 7, 0, 5>, <1, , 0, 7>
FLOAT1FLOAT <1, 23H, 0, 3>, <0, 89H, 1, 5>

3、记录的专用操作符

操作符WIDTHMASK是作用于记录类型的两个专用保留字,利用它们可得到记录类型的不同属性。

操作符WIDTH返回记录或其字段的二进制位数,即其宽度。其一般书写格式如下:

WIDTH 记录名 或 WIDTH 记录字段名

假设有前面定义的记录类型COLOR,那么,WIDTH COLOR的值为8,WIDTH BACK的值为3,WIDTH BLINK的值为1。

操作符MASK返回一个8位或16位二进制数。在该二进制数中,被指定记录或字段使用的对应位的值为1,否则,其值为0。其一般书写格式如下:

MASK 记录名 或 MASK 记录字段名

假设有前面定义的记录类型FLOAT,那么,MASK EXP的值为000FH,MASK DATA的值为1FE0H,WIDTH DSIGN的值为2000H。

  • 记录字段

记录字段名是一个特殊的操作符,它本身也是操作数,其返回值是该字段移到所在记录的最低位所需要的位数,即该字段最低位在记录中的位置。

假设有前面定义的记录类型FLOAT,那么,有:

 MOV CL, EXP相当于MOV CL, 0
 MOV CL, DATA相当于MOV CL, 5

5 标号

标号是一种特殊的标识符,它代表代码段中的某个具体位置,它主要用于表明转移的目标位置。其说明形式如下:

标号:  汇编语言指令   ;注释

解释:标号必须是一个合法的标识符,在其后面紧跟一个冒号":",冒号与汇编语言指令之间要有分隔符。通常用若干个空格、TAB来作分隔符,一般用分隔符使有关内容对齐为宜。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值