2.5表达式与运算符
- 表达式是指令或伪指令语句操作数的常见形式。它由常数、变量、标号等通过操作运算符连接而成。
- 注意:任何表达式的值在程序被汇编的过程中进行计算确定,而不是到程序运行时才计算。
分类:操作运算符分类
- 1.算术运算符
- 2.逻辑运算符
- 3.关系运算符
- 4.数值返回运算符
- 5.属性修改运算符
1.算术运算符
+、—、*、/ 、MOD、SHL、SHR、[ ]
加减乘除、取余符
+、—、*、/ 、MOD
加减乘除、取余
NUM=15*8 ;NUM=120
NUM=NUM/7 ;NUM=17
NUM=NUM MOD 3 ;NUM=2
NUM=NUM+5 ;NUM=7
NUM=-NUM-3 ;NUM=-10
NUM=-NUM-NUM ;NUM=-20
左移、右移符
-
SHL
:左移、右边移出来的空位用0补入。 -
SHR
:右移,左边移出来的空位用0补入。
注意:移位运算符与移位指令区别。
移位运算符的操作对象是某一具体的数(常数),在汇编时完成移位操作。
而移位指令是对一个寄存器或存储单元内容在程序运行时执行移位操作。
NUM=11011011B
MoV AX,NUM SHL 1 ;不能改成:SHL NUM,1
MOV BX,NUM SHR 2
ADD DX,NUM SHR 6
;上面的指令序列等效下面三条指令,移位运算将对象按照与AX等长的16bit数处理
MOV AX,10110110B ;11011011B → 10110110B
MOV BX,00110110B ;11011011B → 00110110B
ADD DX,3 ;11011011B → 00000011B
下标运算符
- 将表达式1与表达式2的值相加后形成一个存储器操作数的地址。
格式:
表达式1[表达式2]
下面两个语句是等效的。
MOV AX,DA_WORD[20H]
MOV AX,DA_WORD+20H
可以用寄存器来存放下标变量例:下面几个语句是等价的
MoV AX,ARRAY[BX][SI];基址变址寻址
MOV AX,ARRAY[BX+SI]
MoV AX,[ARRAY+BX][SI]
MOV AX,[ARRAY+SI][BX]
MOV AX,[ARRAY+BX+SI]
错误示范
MOV AX,ARRAY+BX+SI
MOV AX,ARRAY+BX[SI]
MOV AX,ARRAY+DA_WORD
2.逻辑运算符
分类
- NOT
- AND
- OR
- XOR
- 执行的都是按位逻辑运算。
例
MOV AX, NOT 0F0H => MOV AX,0FF0FH
MOV AL, NOT 0F0H => MOV AL,0FH
MOV BL, 55H AND 0F0H => MOV BL,50H
MOV BH, 55H OR 0F0H => MOV BH,0F5H
MOV CL, 55H XOR 0F0H => MOV CL,0A5H
3.关系运算符
分类
- EQ(等于)
- NE(不等于)
- LT(小于)
- LE(小于等于)
- GT(大于)
- GE(大于等于)
作用
- 关系运算符用来比较两个表达式的大小。比较的两个表达式必须同为常数或同一逻辑段中的变量。
结果
- 若是常量的比较,则按无符号数进行比较
- 若是变量的比较,则比较它们的偏移量的大小。
- 关系运算的结果只能是“真”(全1)或“假”(全0)【0FFH或0FFFFH(8/16位)】
例
MOV AX,0FH EQ 1111B => MOV AX, 0FFFFH
MOV BX,0FH NE 1111B => MOV BX, 0
NUM的16位偏移地址取出来比较
VAR DW NUM LT 0ABH ;当NUM<OABH时,则变量VAR的内容为0FFFFH,否则VAR的内容为0。
4.数值返回运算符
- 有5个,它们将变量或标号的某些特征值或存储单元地址的一部分提取出来。
- SEG、OFFSET、TYPE、LENGTH、SIZE
1.SEG运算符:取变量或标号所在段的段基址。
DATA SEGMENT
K1 DW 1,2
K2 DW 3,4
DATA ENDS
…… ;设DATA逻辑段的段基址为1FFEH,则两条传送指令将被汇编为:
MOV AX ,SEG K1 ;MOV AX,1FFEH
MOV BX ,SEG K2 ;MOV BX,1FFEH
2.OFFSET运算符:取变量或标号在段内的偏移地址。
DATA SEGMENT
VAR1 DB 20H DUP(0)
VAR2 DW 5A49H
ADDR DW VAR2 ;将VAR2的偏移量20H存入ADDR中
DATA ENDS
MOV BX,VAR2 ;(BX)=5A49H
MOV Sr,OFFSET VAR2 ;(SI)=20H
MOV DI,ADDR ;DI的内容与Sl相同
MOV BP,OFFSET ADDR ;(BP)=22H
3.TYPE运算符:取变量或标号的类型属性,并用数字形式表示。对变量:取它的字节长度
变量
BYTE 1
WORD 2
DWORD 4
QWORD 8
TWORD 10
标号
NEAR -1
FAR -2
例如
V1 DB ‘ABCDE’
V2 DW 1234H, 5678H
V3 DD V2
......
MOV AL,TYPE V1
MOV CL,TYPE V2
MoV CH,TYPE V3
经汇编后的等效指令序列如下:
MOV AL,1
MOV CL,2
MoV CH,4
4.LENGTH运算符:该运算符用于取变量的长度。
- 如果变量是用重复数据操作符DUP说明的,则LENGTH运算取最外层DUP给定的值。
- 1.不能取标号;
- 2.标号未给出长度的单位:如DBDW等明。
- 如果没有用DUP说明,则LENGTH运算返回值总是1。
K1 DB 10H DUP(0)
K2 DB 10H,20H,30H,40H ;无DUP说明,取1
K3 DW 20H DUP (0,1,2 DUP (0)) ;取最外层DUP值
K4 DB ‘ABCDEFGH' ;无DUP说明,取1
MOV AL,LENGTH Kl; (AL)=10H
MOV BL,LENGTH K2 ;(BL)=1
MOV CX,LENGTH K3 ;(CX)=20HI
MOV DX,LENGTH K4: (DX)=1
5.SIZE运算符:该运算符只能用于变量,SIZE取值等于LENGTH和TYPE两个运算符返回值的乘积。
1.不能取标号;2.与TYPE有关,统一用B表示长度单位。
例如,对于上面例子,加上以下指令:
MOV AL,SIZE K1 ;(AL)=10H
MOV BL,SIZE K2 ;(BL)=1
MOV CL,SIZE K3 ;(CL)=20H*2=40H
MOV DL,SIZE K4 ;(DL) =1
5.属性修改运算符
这一类运算符用来对变量、标号或存储器操作数的类型属性进行修改或指定。
1.PTR运算符:将地址表达式所指定的标号、变量或用其它形式表示的存储器地址的类型属性修改为“类型”所指的值。
格式:
类型 PTR 地址表达式
类型可以是BYTE(变量、存储器数。)、WORD(变量、存储器数。)、DWORD(变量、存储器数。)、NEAR(标号)和FAR(标号)。这种修改是临时的,只在含有该运算符的语句内有效。
变量、存储器数。
DA_BYTE DB 20H DUP(0)
DA_WORD DW 30H DUP(0)
……
MOV AX,WORD PTR DA_BYTE[10]
ADDBYTE PTR DA_WORD[20],BL
INC BYTE PTR [BX]
SUBWORD PTR [SI], 100
JMPFAR PTR SUB1 ;指明SUB1不是本段中的地址
2.HIGH/LOW运算符:这两个运算符用来将表达式的值分离出高字节和低字节。
格式:
HIGH 表达式 (只能分离出16bit)
LOW 表达式
- 如果表达式为一个常量,则将其分离成高8位和低8位
- 如果表达式是一个地址(段基值或偏移量)时,则分离出它的高字节和低字节。
DATA SEGMENT
CONST EQU 0ABCDH
DA1 DB 10H DUP(0)
DA2 DW 20H DUP (0)
DATA ENDS
MOV AH,HIGH CONST
MOV AL,LoW CONST
MOV BH, HIGH (OFFSET DA1) ;汇编后,马上变为常数;非执行指令时再处理
MOV BL,LoW (OFFSET DA2)
MOV CH,HIGH (SEG DA1)
MOV CL,LoW (SEG DA2)
设DATA段的段基值是0926H,则指令序列汇编后的等效指令为:
MOV AH 0ABH
MOV AL,0CDH
MOV BH,00H
MOV BL,10H
MOV CH,09H
MOV CL,26H
注意:HIGH/LOW运算符不能用来分离一个变量、寄存器或存储器单元的内容,只能放在一个常量前面。
下面语句中的用法是错误的。
DA1 DW 1234H
MOV AH,HIGH DA1
MOV BH,LOW AX
MOV CH,HIGH [SI]
运算符优先级
- 由上至下,依次降低
LENGTH,SIZE,圆括号
PTR,OFFSET,SEG,TYPE,THIS
HIGH,LoW
*,/,MOD,SHR,SHHL
+,-
EQ,NE,LT,LE,GT,GE
NOT
AND
OR,XOR