数据传送指令
通用数据传送指令
MOV
- 格式:
MOV dst,src
- 功能:将
src
传送到dst
- 限制:段寄存器间不可直接相互传送,立即数不能直接送段寄存器,CS 不可作为目的操作数。
PUSH & POP
- 格式:
PUSH src
& POP dst
- 功能:将
src
压栈 & 出栈送入 dst
- 限制:CS 不可作目的操作数
XCHG
- 格式:
XCHG dst,src
- 含义:交换两者(Exchange)
- 限制:段寄存器不可为操作数,也不能同时为存储单元
XLAT
- 格式:
XLAT
- 含义:转换表(Table Look-up Translation)
- 功能:用 AL 内容查表,结果存回 AL,表格位于 DS:BX
地址目标传送指令
LEA
- 格式:
LEA dst,src
- 含义:取有效地址(Load Effective Address)
- 功能:取
src
地址偏移量送dst
- 注:源操作数必须是存储单元,目的操作数必须是除段寄存器之外的 16 位寄存器。
LDS & LES
- 格式:
LDS dst,src
& LES dst,src
- 含义:取双字指针送到目的寄存器和 DS/ES
- 功能:从源操作数指定的存储单元中取出 4 字节,前两个字节送到目的寄存器,后两个字节送到 DS/ES。
标志传送指令
PUSHF & POPF
- 格式:
PUSHF
& POPF
- 含义:将标志寄存器压栈/出栈
- 功能:从源操作数指定的存储单元中取出 4 字节,前两个字节送到目的寄存器,后两个字节送到 DS/ES。
LAHF & SAHF
- 格式:
LAHF
& SAHF
- 含义:Load(Store) AH from(into) Flags
- 功能:将标志寄存器送到 AH & 将 AH 送到标志寄存器
输入输出指令
IN & OUT
- 格式:
IN AL/AX, ADDR
& OUT ADDR, AL/AX
- 功能:从端口地址(寄存器)获取数据送到寄存器(端口地址)
- 地址格式:端口地址有两种格式,小于 FFH 时可以是直接写出,否则必须先送入 DX 再使用。
算术运算指令
加减法指令
ADD & ADC
- 格式:
ADD dst,src
& ADC dst,src
- 含义:(带进位)加法
- 功能:dst = src + dst (+ CF)
INC
- 格式:
INC dst
- 功能:自增 1,dst = dst + 1
SUB & SBB:
- 格式:
SUB dst,src
& SBB dst,src
- 含义:(带借位)减法
- 功能:dst = dst - src (- CF)
DEC:
- 格式:
DEC dst
- 功能:自减 1,dst = dst + 1
NEG:
- 格式:
NEG dst
- 功能:对目的操作数取负,dst = -dst
乘除法指令
MUL & IMUL
- 格式:
IMUL src
& MUL src
- 含义:无符号数/整数乘法
- 功能:只有一个源操作数,当其为 8 位时,AX = AL * src,为 16 位时,(DX,AX)= AX * src
DIV & IDIV
- 格式:
IDIV src
& DIV src
- 含义:无符号数/整数乘法
- 功能:只有一个源操作数作为除数,当其为 8 位时,AX 为被除数,AL 作为商,AH 作为余数。当 src 为 16 位时,(DX,AX)作为被除数,AX 作为商,DX 作为余数。
逻辑运算与移位指令
逻辑运算
指令 | 功能 |
NOT dst | 取反,逻辑非 |
AND dst,src | 逻辑与 |
OR dst,src | 逻辑或 |
XOR dst,src | 异或 |
算术逻辑移位
指令 | 含义 | 功能 |
SAL dst,cnt | Shift Arithmetic Left | 算术左移 cnt 位 |
SAR dst,cnt | Shift Arithmetic Right | 算术右移 cnt 位 |
SHL dst,cnt | Shift Logic Left | 逻辑左移 cnt 位 |
SHR dst,cnt | Shift Logic Right | 逻辑右移 cnt 位 |
cnt 为 1 或者 CL。算术右移时补最高位,逻辑右移补 0,被移出的移入 CF。
循环移位
指令 | 含义 | 功能 |
ROL dst,cnt | Rotate Left | 循环左移 cnt 位 |
ROR dst,cnt | Rotate Right | 循环右移 cnt 位 |
RCL dst,cnt | Rotate through Carry Left | 带进位左移 cnt 位 |
RCR dst,cnt | Rotate through Carry Right | 带进位右移 cnt 位 |
字符串操作指令
指令(字节/字) | 功能 |
MOVSB / MOVSW | 字符串传送 |
CMPSB / CMPSW | 字符串比较 |
SCASB / SCASW | 字符串扫描 |
LODSB / LODSW | 字符串装入 |
STOSB / STOSW | 字符串存储 |
对于后三条指令,操作使用 AL/AX 寄存器(根据操作数类型决定)。
- 源串起始地址为 DS:SI,目的串位于 ES:DI
- 每一次操作都会自动修改 SI 和 DI
- DF 标志位可以控制字符串处理方向,DF = 0 递增,DF = 1 递减,可通过
CLD/STD
设置 - 处理字符串长度放在 CX 中
这些指令前可以用重复前缀 REP
反复执行,或是 REPE/REPZ
相等/为零则重复,REPNE/REPNZ
不相等/非零则重复。
处理器控制指令
标志处理指令
指令 | 含义 | 功能 |
CLC | Clear Carry | CF = 0 |
CMC | Complement Carry | CF = NOT CF |
STC | Set Carry | CF = 1 |
CLD | Clear Direction | DF = 0 |
STD | Set Direction | DF = 1 |
CLI | Clear Interrupt | IF = 0 |
STI | Set Interrupt | IF = 1 |
外部同步指令
ESC
- 格式:
ESC 外部操作码,src
- 功能:用来实现对 8087 协处理器控制。
WAIT
- 格式:
WAIT
- 功能:往往跟在
ESC
后等待,直到 \(\overline{TEST}\) 为低电平。
LOCK
- 格式:
LOCK
- 功能:封锁总线,禁止其他处理器使用总线。
停机和空操作
HLT
- 格式:
HLT
- 功能:进入暂停状态不进行任何操作,直到复位或 NMI 引脚/INTR 引脚出现中断请求信号。
NOP
- 格式:
NOP
- 功能:耗费三个时钟周期但不进行任何操作。
控制转移指令
比较指令
CMP
- 格式:
CMP dst,src
- 功能:用 dst 减去 src,但结果仅反映到标志位,不送回目的操作数。
TEST
- 格式:
TEST dst,src
- 功能:对两个操作数作逻辑与,结果仅反映到标志位,不送回目的操作数。
无条件转移
JMP
- 格式:
JMP dst
- 功能:无条件跳转到目的地址。
跳转分为两种,一种是段内转移或近(NEAR)转移,跳转时仅改变 IP 的值,另一种是段间转移或远(FAR)转移,此时跳转长度超过 IP 最大值,CS 和 IP 都要改变。这两种情况都提供直接转移和间接转移两种方法,前者直接给出目的地址,后者将目的地址放在寄存器或者存储单元中。
类型 | 方式 | 寻址目标 | 举例 |
段内 | 直接 | 立即短转移(8位) | JMP SHORT 标号 |
段内 | 直接 | 立即近转移(16位) | JMP NEAR PTR 标号 或JMP 标号 |
段内 | 间接 | 寄存器(16位) | JMP BX |
段内 | 间接 | 存储器(16位) | JMP WORD PTR 5[BX] |
段间 | 直接 | 立即转移(32位) | JMP FAR PTR 标号 |
段间 | 间接 | 存储器(32位) | JMP DWORD PTR[REG] |
CALL
同样有段内与段间,直接与间接的区分,指令格式与 JMP 类似。
类型 | 方式 | 寻址目标 | 举例 |
段内 | 直接 | 立即调用 | CALL 标号 |
段内 | 间接 | 寄存器(16位) | CALL BX |
段内 | 间接 | 存储器(16位) | CALL WORD PTR 5[BX] |
段间 | 直接 | 立即调用(32位) | CALL FAR PTR 标号 |
段间 | 间接 | 存储器(32位) | CALL DWORD PTR[REG] |
RET
- 格式:
RET (n)
- 功能:过程返回。如果有 n 则在弹出返回地址后再弹出 n 个字节,这一目的是让调用过程可以传递参数。
条件转移
- 格式:
操作符 标号
- 功能:根据操作符,满足即跳转到标号。
直接标志转移
指令 | 测试条件 | 判断条件 |
JC /JNC | CF = 1 / 0 | 有 / 无进位 |
JZ /JNZ | ZF = 1 / 0 | 相等 / 不相等 |
JE /JNE | ZF = 1 / 0 | 相等 / 不相等 |
JS /JNS | SF = 1 / 0 | 符号为负 / 正 |
JO /JNO | OF = 1 / 0 | 溢出 / 无溢出 |
JP /JNP | PF = 1 / 0 | 为偶数 / 奇数 |
JPE /JPO | PF = 1 / 0 | 为偶数 / 奇数 |
无符号数比较测试
指令 | 测试条件 | 判断条件 |
JA /JNBE | CF \(\lor\) ZF = 0 | 高于 / 不低于等于 |
JAE /JNB | CF = 0 | 高于等于 / 不低于 |
JNAE /JB | CF = 1 | 不高于等于 / 低于 |
JNA /JBE | CF \(\lor\) ZF = 1 | 不高于 / 低于等于 |
有符号数比较测试
指令 | 测试条件 | 判断条件 |
JG /JNLE | (SF \(XOR\) OF) \(\lor\) ZF = 0 | 大于 / 不小于等于 |
JGE /JNL | SF \(XOR\) OF = 0 | 大于等于 / 不小于 |
JNGE /JL | SF \(XOR\) OF = 1 | 不大于等于 / 小于 |
JNG /JLE | (SF \(XOR\) OF) \(\lor\) ZF = 1 | 不大于 / 小于等于 |
循环控制指令
LOOP
- 格式:
LOOP 标号
- 功能:跳至标号继续循环,每执行一次 CX 减一,若减一后为零则不跳转。
LOOPE & LOOPNE
- 格式:
LOOPE 标号
& LOOPNE 标号
- 功能:(不)相等时循环,其他与 LOOP 相同。
LOOPZ & LOOPNZ
- 格式:
LOOPZ 标号
& LOOPNZ 标号
- 功能:结果(不)为零时循环,其他与 LOOP 相同。
JCXZ
- 格式:
JCXZ 标号
- 功能:CX 为零则跳转,否则就往下执行, CS 不会减一。
中断指令
INT
INTO
- 格式:
INTO
- 功能:如果溢出标识 OF 为 1 则产生类型为 4 的中断,否则就继续向下执行。
IRET
BIOS & DOS 调用
调用这两者用的是 INT 中断指令。
其中 n = 21H 是最为强大的 DOS 中断。一般调用中断须先将参数放入指定寄存器,功能号放入 AH,子功能号放入 AL,例如
常用的功能号有
功能号 | 功能 | 参数 |
01H | 输入一个字符 | AL = 输入字符 |
0AH | 输入字符串 | DX:DX = 缓冲区首地址 |
02H | 显示一个字符 | DL = 显示字符 |
09H | 显示 $ 结尾的字符串 | DX:DX = 字符串首地址 |