8086CPU中的标号与变量
8086中汇编语句的种类
指令语句
凡是CPU能执行的语句,或者说能汇编成指令代码的语句。
伪指令语句
CPU不能执行的语句,或者说不能汇编成指令代码的语句。
如前面提到过的伪指令 \(DB\),只是告诉masm.exe在汇编的过程中执行的操作:在汇编时定义一个字节数据。而不是告诉CPU要去执行什么。
宏指令语句
本身是8086指令系统没有的语句,是用户用 宏定义伪指令 定义的一条新的语句。
汇编语言中语句的组成
如
data1 DW 1234H,5678H
data1是将存储单元的地址符号化,起一个符号名字,方便程序设计。data1表示的就是定义的这段存储空间的首地址,称为变量名。和标号名不同。
DW表示的是定义的是字变量,其后的每个逗号隔开的为一个字数据,也就是占两个存储单元.data1表示这两个字数据的首地址,(1234H/5678H各占用一个字空间,所以12/34/56/78各占用一个字节)低位数据放在低地址,用字低字节所对应的地址当作整个字的地址,存放情况如下图所示:
data1-------->34H
data1+1----->12H
data1+2----->78H
data1+3----->56H
如果按字访问第二个数据,可以MOV AX,data1+2
data2 DW ?
data2 DW ?定义了一个字空间,首地址变量名为data2,?表示开始定义时没有具体的数据,实际数据是随机的,开机是多少就是多少。
上面语句中,语句由三部分组成,而分号后还可以加注释,所以语句最多由四部分组成
- 变量名
- 助记符
- 操作数
- 注释
NEXT:mov AX,BX
...
ADD AX,DAT
JZ NEXT
执行过程:将BX的值送给AX,再将AX和DAT相加后结果送给AX,如果和为0,就跳到mov AX,BX这条语句重新执行。JZ后面是目的地的地址。对于程序员来说,这个地址很难的出来,我们可以将其符号化。
NEXT为mov AX,BX这条语句在存储器中的地址的符号名字,必须以冒号结尾,我们称为标号名。
可以看出,标号是对指令的地址取一个别名,而变量是对存储单元的地址取一个别名。
标号
标号一旦定义了,就具有三个属性:
- 段地址属性
- 段内偏移地址属性
- 类型:NEAR和FAR
类型分为两种,如果 JZ 转移指令和目的地地址在同一个代码段,就是段内转移,段内转移类型就是NEAR,近程转移,标号在8086里面被赋予-1的值。
不在同一个代码段就是段间转移,也叫远程转移,类型是FAR,8086中被赋予-2的值。
但是获取一个标号的类型属性是没有意义的。
可以使用 属性表达式 获取标号的属性
- 段地址属性:SEG
- 段内偏移地址属性:OFFSET
- 类型:TYPE
如
mov BX,OFFSET NEXT
OFFSET NEXT获取标号所代表的段内偏移地址,是个常数,标号一旦定义就无法更改,是不变的。
变量及其定义伪指令
变量是CPU可操作的一段存储空间,可以读写,而标号不行。
DB:定义字节型变量
DW:定义字型变量
DD:定义双字型变量
一般变量定义在数据段DS,如
data1 DB 12H,12
变量一旦定义了,就具有5个属性
- 段地址属性
- 段内偏移地址属性
- 类型
- 长度
- 大小
8086对变量类型的值,等于其所占存储单元,比如DB类型就是1,DW类型就是2
可以使用 属性表达式 获取标号的属性
- 段地址属性:SEG
- 段内偏移地址属性:OFFSET
- 类型:TYPE
- 长度:LENGTH
- 大小:SIZE
长度是在变量定义语句中,所定义的变量的个数(DUP重复次数,没有DUP长度属性就是1)
大小就是所有变量所占的总的字节数。
data1 DB 12H
mov AL,TYPE data1
AL值就是1
操作数表达式是在汇编过程完成,等效于mov AL,1
data2 DB ?
data3 DW data2
data3代表的存储空间里面放的是data2的单字属性,段内偏移地址
data4 DD data2
data4放的是data2的双字属性,段地址加段内偏移地址属性
后面寻址方式详解。
data5 DB 4 DUP(?)
DUP是重复操作符,DUP左边数字表示重复4次,开拓了4个字节空间,初始放入的是随机的数据,第一个字节地址可以用data5表示。
汇编语言允许DUP嵌套操作。
data5 DB 7 DUP(4 DUP(?))
将4 DUP(?)操作又重复7次。
data1 DB 12,12H,-12
...
mov AX,data1
将data1地址中的内容送给AX。
但这条语句汇编会出错,因为AX是16位,data1是字节数据,前后类型不一致。需要类型转换。
在8086汇编语言中,提供了 \(PTR\) 强制转换。
可以改为
data1 DB 12,12H,-12
...
mov AX,WORD PTR data1
AX中内容就为120CH, 但是data1离开这条语句后仍然是字节型变量。
PTR是属性临时修改操作符。在实际汇编语言中用的很多。
mov [BX],10H
将10H送给按BX内容间接寻址的一个存储空间,但是[BX]无法推断出该空间的类型(字节/字/双字?),后面的10H是个常数,显然也没有类型,所以这条语句是有问题的,汇编错误——类型不明确。
假如这个单元是字节单元,我们可以用PTR说明:
mov BYTE PTR [BX],10H
这条就对了。