指令系统(四)
汇编语言指令(一)
数据传送指令(7种)
除 SAHF,POPF
外,其余传送指令CPU执行后,对6个状态标志位(PSW
)无影响
语法规则
- 立即数只能做源操作数
- 类型要一致
- 类型要明确
- 当
DS、ES、SS
作为目的时,源操作数不能是立即数IP
不能做目的- 两存储器单元之间不能直接操作
- 不允许两个变量直接参加运算
通用数据传送指令 MOV
格式:MOV DST, SRC
取有效地址指令 LEA
格式:LEA REG16, MEM
REG16
:16位寄存器
MEM
:5种寻址方式之一指明的存储单元
注意:REG16
最好使用 BX、BP、SI、DI
例:取DAT1
的有效地址,放入BX
MOV BX, OFFSET DAT1
;等价于
LEA BX, DAT1
取地址指针指令 LDS/LES
格式:LDS/LES REG16, MEM
指令说明:
MEM
所指向的是一个32位(双字)存储空间,运行完指令后,将MEM
所指向的存储空间的高16位存入DS/ES
中作为段地址,将MEM
所指向的存储空间的低16位存入REG16
中作为偏移地址
例:某数x(字)所在存储单元的地址指针在 POINT
双字单元中,将x取出放入 DX
中
;法一
LDS BX, POINT
MOV DX, [BX]
;法二
LES BX, POINT
MOV DX, ES:[BX]
标志传送指令 LAHF/SAHF
源和目的操作数均为隐含寻址
格式:
LAHF ;(AH)<--PSW低8位
SAHF ;(AH)-->PSW低8位
数据交换指令 XCHG
格式:XCHF DST, SRC
说明:
DST、SRC
均不能用立即数- 段寄存器不能参加交换
例:
XCHG AX, BX ;(AX)<-->(BX)交换
XCHG AL, [SI+3] ;寄存器相对寻址
XCHG DH, DL ;DX高低8位互换
XCHG AX, ES ;语法错误,段寄存器不能参加交换
XCHG AX, BL ;语法错误,类型不一致
字节转换指令 XLAT
- 源和目的操作数均为隐含寻址
- 又名 查表指令
格式:XLAT ;AL<--(DS:(BX)+(AL))
例:有表:TAB DB 30H, 31H, 32H, 33H,... ,39H
,取出字符 ‘4’
MOV AL, 4 ;偏移地址存入AL,第4个字符
LEA BX, TAB ;取出TAB的地址
XLAT ;(AL)<--34H
堆栈操作指令 PUSH/POP/PUSHF/POPF
格式:
PUSH SRC
:压栈,SRC不能是立即数POP DST
:出栈PUSHF
:将PSW压栈POPF
:将栈内一个字赋给PSW
说明:都必须按字操作
算术运算类指令(6种)
注意:
- CPU只要涉及运算,其结果就会影响6个状态标志
- 段寄存器不能参加运算(算术、逻辑)
加法指令 (3条)
- 不带进位位加法:
ADD DST, SRC ;DST<--(SRC)+(DST)
,根据结果设置6个状态标志 - 带进位位加法:
ADC DST, SRC ;DST<--)(SRC)+(DST)+CF
,根据结果设置6个状态标志 - 增一指令:
INC DST ;DST<--(DST)+1
,设置除CF
以外的状态标志,对CF
没影响
例:设在DVAR
开始的连续8字节中分别存放着两个数A和B(每个数32位),求C=A+B
,并将结果C放到DVARC
开始的内存中
解:设
A=00127654H
,B=00049821H
,则在数据段中有变量定义语句:DVAR DD 00127654H ;A DD 00049821H ;B DVAR DD ? ;存放结果C
代码段
LEA SI, DVAR ;取DVAR的偏移地址 MOV AX, [SI] ;取A的低字到(AX) ADD AX, [SI+4] ;AX与B的低字相加 MOV WORD PTR DAVRC, AX ;将结果存到C的低字 MOV AX, 2[SI] ;取A的高字到(AX) ADC AX, [SI]+6 ;注意考虑进位,用ADC,AX与B的高字相加 MOV WORD PTR DAVRC+2, AX;将结果存入C的高字
减法指令(5条)
-
不带借位位减法:
SUB DST, SRC ;DST<--(DST)-(SRC)
,根据结果设置6个状态标志 -
带借位位减法:
SBB DST, SRC ;DST<--(DST)-(SRC)-CF
,根据结果设置6个状态标志 -
减一指令:
DEC DST ;DST<--(DST)-1
,设置除CF
以外的状态标志,对CF
没影响例:若
(AL)=0FFH
,CF=0
,则CPU执行:INC AL
指令后,(AL)=?
,CF=?
由于
AL
只能放8位,所以(AL)=0
INC
和DEC
不影响CF
,所以CF=0
-
比较指令:
CMP DST, SRC ;(DST)-(SRC)
,根据差设置6个状态标志当程序做减法或比较时,会产生以下5个条件(
CF、SF、ZF、PF、OF
),AF
不是条件
条件转移指令(插入节,18条)
一般在比较指令后,会紧跟条件转移指令,根据产生的条件决定程序的转向。假设执行完指令:
MOV AL, a
CMP AL, b ;即a-b
根据单个条件,每个条件对应两条指令,共10条:
- 根据
CF
:JC 标号
:结果产生进/借位,则转移JNC 标号
:结果没有产生进/借位,则转移
- 根据
SF
:JS 标号
:结果为正,则转移JNS 标号
:结果为负,则转移
- 根据
ZF
:JZ/JE 标号
:结果为0(相等),则转移JNZ/JNE 标号
:结果不为0(不相等),则转移
- 根据
PF
:JP 标号
:结果有偶数个1,则转移JNP 标号
:结果有奇数个1,则转移
- 根据
OF
:JO 标号
:结果溢出,则转移JNO 标号
:结果没有溢出,则转移
假设 a,b
相比较,把 a,b
看成无符号数和有符号数结果显然不同,故还有以下8条比较指令
-
a、b
是无符号数(4条)无符号数不存在大小关系,只存在高低关系。相等:
E
,高:A
,低:B,比如:JNAE
的含义是“not A and E
”也就是B
,即低于JB/JNAE 标号
:a低于b,则转移JBE/JNA 标号
:a低于等于b,则转移JA/JNBE 标号
:a高于b,则转移JAE/JNB 标号
:a高于等于b,则转移
-
a、b
是有符号数(4条)有符号数存在大小关系,相等:
E
,大:G
,小:L
JL/JNGE 标号
:a小于b,则转移JLE/JNG 标号
:a小于等于b,则转移JG/JNLE 标号
:a大于b,则转移JGE/JNL 标号
:a大于等于b,则转移
注意:上节课说过,这些都是有条件转移,也就是转移范围是 -128~+127
之间
------------------------------分割线----------------------------------------
书接上回,减法第5条指令
- 求负指令:
NEG DST ;DST<--0-(DST)
,根据结果设置6个状态标志
例:在存储器BUFFER单元,有一个16位的带符号数,求该数的绝对值,并把结果放回原处
```assembly
;定义DS段
BUFFER DW ?
;定义代码段
START: MOV AX, BUFFER
CMP AX, 0
JNS EXIT
NEG AX
MOV BUFFER, AX
EXIT: END
```
乘法指令(2条)
乘法指令包括无符号数乘法和与符号数乘法
- 无符号:
MUL SRC
- 有符号:
IMUL SRC
注意:
- 指令中
DST
为隐含的被乘数,存在寄存器AX
中 - 乘法只有字节乘和字乘,哪种类型是由
SRC
的类型决定
- 字节乘:
(AL) * SRC --> AX(AH:AL)
,高位存余数,地位存商 - 字乘:
(AX) * SRC --> DX:AX
指令执行后只影响 CF、OF
,其余状态标志 没定义(值不确定,没意义)
对于无符号数:
CF |
OF |
说明 |
---|---|---|
0 |
0 |
高半部积无效(AH/DX=0 ),只需处理低半部(AL/AX ) |
1 |
1 |
高半部有有效积 |
对于有符号数:
CF |
OF |
说明 |
---|---|---|
0 |
0 |
高半部积无效(高半部是低半部积符号位的扩展),只需处理低半部(AL/AX ) |
1 |
1 |
高半部有有效积 |
符号位的扩展:低半部的符号位为
0/1
,高半部全部扩展为0/1
除法指令(2条)
-
无符号除法:
DIV SRC
-
带符号数除法:
IDIV SRC
注意:
-
对于无符号除法,又分为字节型除法和字型除法,哪种类型是由
SRC
的类型决定- 字节型除法:被除数隐含在
AX
(16位)中,源操作数是8位。商(AL
),余数(AH
) - 字型除法:被除数隐含在
DX:AX
(32位)中,源操作数是16位。商(AX
),余数(DX
)
- 字节型除法:被除数隐含在
-
对于带符号数,分为下面4种情况
被除数 除数 商 余数 +
+
+
+
+
-
-
+
-
+
-
-
-
-
+
-
例:将存储器BUFFER1
中的字节型无符号二进制数转化为十进制数,并将转化结果一分离BCD数的形式存入BUFFER2
与下的单元
分析:字节型无符号二进制数范围是0-255,三位数,所以要用3个字节
;DS段
BUFFER1 DB ?
BUFFER2 DB 3DUP(?)
;CS段
MOV AL, BUFFER1
MOV AH, 0 ;字节型,要清零
MOV CL, 10 ;除数
DIV CL
MOV BUFFER2, AH ;余数,即个位
MOV AH, 0 ;清零
DIV CL
MOV BUFFER2+1, AH ;余数,即十位
MOV BUFFER2+2, AL ;商,即百位
符号扩展指令(2条)
CBW ;(AL)-->AX(AH:AL)
CWD ;(AX)-->DX:AX
例:求 Y=a*b+c-18
,其中 a、b、c
是字节型变量
;DS段定义
DATA DB ?
DATB DB ?
DATC DB ?
DATY DB 0
;CS段程序
MOV AX, DATA ;准备乘数a
IMUL DATB ;乘法运算a*b
MOV BX, AX ;把积保存到BX
MOV AL, DATC ;积与DATC类型不一致,不能直接计算
CBW ;调整类型
ADD AX, BX ;再相加
SUB AX, 18 ;再进行减法
MOV DATY, AX ;将最终结果送到DATY
BCD数调整指令(6条)
+、-
分为分离BCD数和组合BCD数调整
*、÷
只有分类BCD数调整
注意:
+、-、*
先运算后调整÷
先调整后运算
加法BCD调整
隐含对AL
内容调整
- 组合:
DAA
- 分离:
AAA
例1:计算 56+73
MOV AL, 56H
ADD AL, 73H ;结果:1100 1001
DAA ;调整
调整:高4位和低4位,超过9就加6,结果:
1 0010 1001-->0010 1001=29
,产生进位使CF=1
,最终结果129
例2:计算 4+8
MOV AL, 04H
ADD AL, 08H ;结果:0000 1100
AAA ;调整
调整:
- 低位超过9就加6,高位不变,可能产生进位(
AF=1
),影响PSW
- 使高4位清零,低4位不变,此时
AX=0002H
- 把
AF
给CF
和AH
,最终结果AX=0102H
注意::分离BCD码调整指令,又名 ASSII码调整指令
,比如上例中 4+8<-->'4'+'8'
减法BCD数调整
隐含对AL
内容调整
- 组合:
DAS
- 分离:
AAS
例:计算 31-87
MOV AL, 31H
SUB AL, 87H ;结果:1010 1010,借位1即(CF=1)
DAS ;调整
调整:
- 对1010 1010,超过9就减6,结果:0100 0100=44H
- 由于借位1,即十进制借了100,故最终结果是44-100=56
乘法BCD数调整
- 分离:
AAM
例:计算 7*8
MOV AL, 07H
MOV BL, 08H
MUL BL ;(AX)=0038H,期望:0506H
AAM ;调整
调整:
AX
÷10-->商:AH
,余数:AL
,即(38H)除以10,商5余6-->0506H
(38H=56)
除法BCD数调整
隐含对AL
内容调整
- 分离:
AAD
例:计算 27÷4
MOV AX, 0207H
MOV BL, 04H
ADD ;(AH)*10+(AL)-->(AX),即02H*10=14H,14H+07H=1B
DIV BL