数据传送指令
1. 通用数据传送指令 MOV,PUSH,POP,XCHG,XLAT
(1)MOV
①MOV DS, 2000H ; //语法错误,不能用立即数给段寄存器赋值。
应该为:MOV AX, 2000
MOV DS, AX
② MOV WORD PTR[DI], 2000H
PTR 是属性运算符,功能为修改操作数的类型。WORD PTR 的作用是将操作数的类型 设置为字类型。
③MOV [DI], 04AH ; //语法错误:源和目的操作数的类型都不确定,产生二异性。
因为[DI]代表的仅是首地址,不能确定它具体有多少个地址;而04AH也不能确定它前面有多少个0,占的字节数自然也不确定。
注意:
① MOV 指令不影响标志寄存器的任何标志位
② 源和目的操作数必须等长,即同时为字节类型或字类型。
③不允许给 CS(代码段寄存器) 赋值。
④ MOV 指令不能访问 IP 和 Flags
(2)PUSH,POP
PUSH 和 POP 是堆栈操作指令助记符。堆栈是程序在内存中开辟的一个数据区,用以 保存寄存器或存储器中暂时不用而又必须保存的数据。
程序中堆栈是用段定义语句在内存中 定义的一个堆栈段,堆栈段的段基址存放在 SS 寄存器,段内偏移地址存放在 SP 寄存器中, SP 也常称为堆栈指针,它总是指向栈顶。
例如: 设 SS=2000H,SP=102H,AX=623EH,执行下面指令后:
PUSH AX
AX 的数据 62H 存入 20101H 单元,3EH 存入 20100H 单元,SP=0100H
注意:
- 堆栈指令的 操作数必须是字类型,可以是 16 位的通用寄存器或段寄存器,也可以是两个连续的内存单 元,可以采用任何寻址方式。
- CS 不能作为 出栈指令的操作数。
- 堆栈指令不影响任何标志位。
2. 输入输出指令 IN,OUT
8086CPU 对所有输入输出端口统一管理,提供了一个与内存储器地址空间分开的、完 全独立的地址空间,I/O 端口的地址有 8 位和 16 位两种形式。
- 直接端口寻址方式:当端口地址是 8 位的二进制数时,可以在指令中直接使用该地址。
- 寄存器间接寻址方式:当端口地址为 16 位,不能直接使用,需要预先将其传送到 DX 寄存器中,并且只能是 DX 作为间接寻址寄存器
8086CPU 无论从端口输出数据还是输入数据,都要通过累加器 AL 或 AX(只有这两个寄存器),所以输入输 出指令又称为累加器专用传送指令。
IN AL, 60H ;从 60H 端口输入一个字节。
MOV DX, 0378H
MOV AL, ‘A’
OUT DX, AL //三条代码表示从并行口 0378H 输出一个字符‘A’
3. 乘法指令 MUL,IMUL,AAM
(1)无符号数乘法指令 MUL
功能:如果 src 为字节类型,累加器 AL 与 src 相乘,结果存在 AX 中;如果 src 为字类 型累加器 AX 与 src 相乘,结果存在 DX:AX 中。
说明:两个乘数的数据类型要相同,指令影响标志位 CF,OF 位。 例如:
MUL AH ;AL×AH 结果保存在 AX 中。
MUL BX ;AX×BX 结果保存在 DX:AX 中。
MUL BYTE PTR[SI] ;AL×[SI]结果保存在 AX 中。
MUL WORD PTR[BX+DI] ;AX×[BX+DI]结果保存在 DX:AX 中。
字节相乘的乘积在 AX 中,如果标志位 CF=OF=1,表明 AH 不为 0;字相乘的乘积在 DX:AX 中,如果标志位 CF=OF=1,表明乘积的高位 DX 不为 0。
(2)有符号数乘法指令 IMUL
功能:指令的功能和用法与 MUL 指令相同,只是操作数为带符号数,结果也是带符号 数。
(3)乘法的十进制调正指令 AAM
AAM 指令完成 AL 中数的调正。使用 AAM 的前提是两个非压缩 BCD 码相乘,乘积在 AL 中,AH=0。
功能:把 AL 寄存器的内容除以 0AH,商存在 AH 中,余数存在 AL 中。 例
MOV AL, 8
MOV BL, 7
MUL BL
AAM ;AH=5,AL=6
4. 除法指令 DIV,IDIV,CBW,CWD,AAD
除法指令包括无符号数除法指令 DIV,带符号数除法指令 IDIV。这两条指令都隐含了 被除数 AX 或 DX:AX。
除数可以是寄存器或存储器操作数,但不能是立即数。
被除数的字 长要求是除数字长的两倍,如果除数是字节类型,被除数必须是字类型而且要预置在 AX ,结果的商存到 AL 中,余数存到 AH 中; 如果除数为字类型,被除数必须是双字类型而且要预置在 DX:AX 中,结果的商存到 AX 中,余数存到 DX 中。
DIV BL
DIV BX
DIV BYTE PTR[SI]
DIV WORD PTR[DI]
如果字节操作的结果大于 FFH 则溢出,如果字操作的结果大于 FFFFH 则溢出,溢出将 产生除法错中断。
例子:MOV BL DIV BL
(2)带符号数的除法 IDIV
IDIV 指令与 DIV 指令相似,只是参加运算的是带符号数,结果也是带符号数,符号与 被除数一致。被除数什么符号余数也是什么符号
(3)符号扩展指令 CBW,CWD 除法指令对操作数的长度严格要求,如果长度不符合要求,可以使用符号扩展指令对数 据类型进行调整。指令不影响标志位。
-
指令格式:CBW
功能:字节转换为字,如果 AL<80H,则 AH 置 0;如果 AL≥80H,则将 FFH 赋给 AH。
说明:将 AL 中的数的符号位扩展至 16 位,扩展的符号部分存入 AH 中,即由 AL 扩 展为 AX,值保持不变。 例如:
MOV AL, 3EH ;AL=0011 1110B CBW ;AX=0000 0000 0011 1110B MOV AL, 93H CBW ;AX=1111 1111 1001 0011B
-
指令格式:CWD
功能:字转换为双字,如果 AX<8000H,则 DX 置 0;如果 AX≥8000H,则将 FFFFH 赋给 DX。
说明:CWD 将 AX 中的数的符号位扩展至 32 位,扩展的符号部分存入 DX 中。即由 DX:AX 代替 AX,值保持不变。 例如:
MOV AX, 0C539H ;AX=1100 0101 0011 1001B CWD ;DX=FFFFH,AX=C539H
(4)除法调正指令 AAD
AAD 指令进行除法调正的使用范围有限,它只能用于两位的非压缩 BCD 的除法操作, 也就是不超过 99 的十进制数的除法操作。AAD 指令与其它调正指令不同,它用在除法指令 之前,即在除法执行之前首先用 AAD 指令将 AX 中两位非压缩 BCD 码调正为二进制数, 然后再进行二进制除法。
功能:AH×10+AL 送入 AL,AH=0。 例如:
MOV AX, 0908H ;AX=0908H,AX 存有非压缩 BCD 数 98
MOV BL, 8
AAD ;AX=09×0AH+08=92H
DIV BL ;AH=2,AL=0CH
逻辑运算指令
逻辑运算指令包括与(AND)、或(OR)、非(NOT)、异 或(XOR)和测试(TEST)指令.
(5)测试指令 TEST
指令格式: TEST OPRD1, OPRD2
功能:OPRD1 与 OPRD2 按位进行与操作,(与AND指令功能一样)但是结果不回送 OPRD1 中,所以指令执行 后两个操作数的值保持不变。
例:
TEST AL, 01H
指令执行后 AL 的值保持不变,但标志位受到影响。如果 ZF=0 说明 AL 的第 0 位为 1, 如果 ZF=1 说明 AL 的第 0 位为 0。
串操作指令
串或字符串是指在内存中连续存放的由字节或字组成的数据串,可以是数值型或字符型 数据。我们常常要从数据串中查找特定数据;或者比较两个串是否相同等,或者把一个串从 内存的一个区域传送到另一个区域等操作;使用串操作指令就是最佳选择。串操作指令对串 中数据进行相同的操作,可以以字节为单位或以字为单位,可操作的最大串长度为 64K。串 操作指令包括:
MOVS 串传送
CMPS 串比较
SCAS 串扫描
STOS 存入串
LODS 取串
这五种串操作指令都是隐含指令,说明如下:
① 源操作数(源串)默认由 DS:SI 指定,即源串默认在数据段,允许段超越为 CS、ES 和 SS。偏移地址指针 SI 自动修改。
② 目的操作数(目的串)默认由 ES:DI 指定,即目的串默认在附加数据段。不允许段 超越。偏移地址指针 DI 自动修改。
③ 通过设定标志寄存器中的方向标志位DF的值,可以控制串操作的方向。 DF设定为0, 偏移地址指针 SI 和 DI 自动增量,如果串操作为字节操作,每次偏移地址指针加 1,如果为 字操作,每次偏移地址指针加 2。DF 设定为 1,偏移地址指针自动减量。如果串操作为字节 操作,每次偏移地址指针减 1,如果为字操作,每次偏移地址指针减 2。
④ 串操作指令本身只操作一次,例如指令 MOVSB 的功能为将 DS:SI 指明的一个字节 传送到 ES:DI 指明的内存单元中。如果要使整个的源串数据全部传送到目的串中,需要再加 一个重复前缀 REP。用于串操作指令的重复前缀有三种,分别是: REP:无条件重复前缀 REPE:相等时重复(ZF=1), REPZ:比较结果为 0 时重复 REPNE:不相等时重复(ZF=0), REPNZ:比较结果不为 0 时重复
⑤ 带重复操作前缀的串操作指令,需要指明重复次数。用计数器 CX 指定串长度,即重 复次数,每次串操作后 CX 自动减 1,直到 CX=0,串操作结束。 综上所述:在使用串操作指令前应预先设置源串指针 DS:SI,目的串指针 ES:DI,计数 器 CX 和标志位 DF。
**1. 串传送指令 MOVS **
功能:字符串传送。
- MOVSB,隐含操作数,将 DS:SI 指明的一个字节传送到 ES:DI 指明的内存单 元中。
- MOVSW,隐含操作数,将 DS:SI 指明的两个字节传送到 ES:DI 指明的内存单 元中。
- MOVS OPRD1,OPRD2,这种形式常常用在源串段超越的情况下。
将数据段中 STRING 1 中 100 个字节传送到附加数据段中的 STRING 2 中:
MOV SI, OFFSET STRING1 ;初始化源串指针
MOV DI, OFFSET STRING2 ;初始化目的指针
MOV CX, 100 ;初始化计数器
CLD ;设置 DF=0,使 SI 和 DI 按增量变化,增量为 1 |
相反功能指令是STD,将方向标志位DF置1
REP MOVSB ;自动重复传送,直到 CX=0
如果希望一次传送两个字节,则程序改为:
MOV SI, OFFSET STRING1
MOV DI, OFFSET STRING2
MOV CX, 50
CLD
REP MOVSW
如果 STRING 1 在附加数据段中,程序应为:
MOV SI, OFFSET STRING1
MOV DI, OFFSET STRING2
MOV CX, 100
CLD
REP MOVS BYTE PTR ES:[DI], BYTE PTR ES:[SI]