目录
上一章主要提到了汇编语言的各种指令,但是根据对高级语言的认知来看,每条指令需要传递变量或者参数。本节就来讲述参数、变量和符号。
数值型(常参)常数和表达式
数值型参数包含常数和表达式。其中,常数是一个固定的数值,而表达式间接给出了一个数值。
常数
常数的定义比较广泛,通常分为以下几种:
- 十进制常数:由0~9组成,以字母D/d结尾或者省略结尾(这是因为汇编语言对大小写不敏感)。例如: 34d 或者34表示十进制常数34,在内存中表达为22。
- 十六进制常数:和DOS表达的内存数值进制形式相同,以字母H/h结尾。如果是以字母开头的十六进制数,还需要在最前面加0,避免与其他符号混淆。例如:无符号数64H表示十进制常数100,0FFH表示十进制常数255
- 二进制常数:以字母B/b结尾。例如01101100B。
- 八进制常数:以字母Q/q结尾。比如144Q。
- 字符串常数:缩略号括起来的单个或者多个字符。
- 符号常数:利用标识符表达的一个数值。可以使用符号名替代上面四种以及表达式来简化程序,提高可读性。类似于C语言的#define。其基本格式如下:
name EQU constant name EQU <string> name = expression
由上可以看出,汇编语言区分进制是靠后置字符(B,Q,D,H)区分的。省略后缀时,默认为十进制。当然,在实际使用时,可以使用.RADIX指令改变默认进制。
表达式
汇编语言一样允许传递数值确定的表达式。表达式中允许含有以下运算符:
- 算术运算符+,-,*,/,MOD
- 逻辑运算符AND,OR,XOR,NOT
- 移位运算符SHL,SHR
- 关系运算符EQ,GT,LT,GE,LE
- 高低分离符HIGH,LOW,HIGHWORD,LOWWORD。这是单目运算符,操作数必须是符号常量。不能是一般常数。
- MASM规定的一些其他运算符。根据MASM手册的规定决定。
总而言之,汇编语言许多常量的定义和后面出现的高级语言如出一辙,但是汇编语言里面某些位的操作符变得更加常用。
变量定义伪指令
变量定于伪指令为便改良申请固定长度的存储空间,并且可以同时进行初始化。该类伪指令是最常使用的伪指令之一。其基本格式为:
name cmd init ;变量名 伪指令 初值表
初值表初始化
初值表初始化一般用逗号分别参数,可以是数值常数,表达式或者‘?’,‘DUP’组成。其中‘?’表示不初始化,‘DUP’表示重复初始化,下面给出DUP的格式和例子。
重复次数 DUP (重复参数)
array DB 10 DUP (0) ;array初始化为10个字节,每个字节都是0组成的数组
类型伪指令
定义变量时可以分配新的内存单元供变量存储。类型伪指令包含DB,DW,DD,DF,DQ,DT等指令,各个指令的基本格式如下:
DB ;定义字节单元define byte,可以定义多个单元,每个单元占1字节
DW ;定义字单元define word,同上
DD ;定义双字单元define double word,同上
DF ;定义三字伪指令,通常表示48位远指针
DQ ;定义四字伪指令,通常表示64位整数long long
DT ;定义10字节伪指令
从MASM6.0开始,上述指令被建议改为BYTE,WORD,DWORD,FWORD,QWORD,TBYTE。
定位伪指令
除了类型伪指令之外,还可以定义数据或者指针所在的偏移地址,利用现有的存储单元。定位伪指令包含ORG,EVEN和ALIGN指令。这三个指令的基本格式如下:
ORG 0100H ;从100H开始安排数据或者程序
ORG $+10 ;偏移地址加10,其中$表示当前的偏移地址
EVEN ;使得当前的偏移地址指针指向偶数地址。若已经偶数不变化,否则跳跃到下一个偶数地址。一般可以用于对齐字量数据。
ALIGN N ;使得当前的偏移地址指针指向模N地址。变化规则和EVEN相同。一般对齐2的乘方(2,4,8,16,……)
这些指令也可以在代码段中使用,和JMP类似。
变量和标号属性符号
变量和标号一般具有两种属性:地址属性和类型属性。其中,地址属性表示对应存储单元的逻辑地址,一般包含段地址和偏移地址。类型属性对应段内或者段间,数据单元类型等等。
地址操作符
我们先前已经见到一些地址操作符,例如[ ]表示取地址操作符,$表示当前的偏移地址,:表示段前缀操作符。此外还有一些经常应用的地址操作符:
OFFSET 名字/标号 ;返回名字或者标号的偏移地址
SEG 名字/标号 ;返回名字或者标号的段地址
OFFSET是一个非常常用的指令,之前在实验中遇到过OFFSET取得字符串的偏移地址输出字符串的实例,OFFSET还常常用于代码段指令中,使用OFFSET DONE-OFFSET START(START和DONE对应主程序中某段指令开头结尾)来得到主程序的以字节为单位的长度。
类型操作符
类型操作符包含PTR指令,THIS指令和TYPE指令,还包括MASM定义的其他属性操作符,包括SIZEOF和LENGTHOF操作指令。
ptr指令在8086数据传送指令中已经见过,一般用法是使得两个操作数的存储类型对齐。例子如下:
MOV AL, byte ptr [BX+SI] ;[bx+si]可能是字单元数据,在此被转换为字节数据,只传低字节。
this指令说明操作数具有汇编时的当前逻辑地址,但是就具有指定的类型,类型名和ptr操作符中的类型一样。如下是一个例子:
b_var equ this byte ;按字节访问b_var,但是和变量w_var地址相同
除此之外,MASM中还提供了一个LABEL伪指令,其功能等同于equ this。
type指令返回一个字量值,表明名字或者标号占据的字节空间量。
常数 | 0 |
结构 | 每个结构占据的字节数 |
变量 | 该变量数据占据的字节数 |
标号 | 距离属性值,根据短转,近转和远转分别为FF01,FF02和FF05 |
寄存器 | 该寄存器所具有的字节数,r8是1,r16 是2 |
复习:在128字节内的转移属于短转移;同段内128字节外的转移属于近转移;段间属于远转移。
关于更详细的关于属性的应用,请参见XMU汇编语言实验04.