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