566 lines
13 KiB
Markdown
566 lines
13 KiB
Markdown
# 附录三:汇编指令集
|
||
|
||
## 一、数据传送指令
|
||
|
||
### 1. 通用数据传送指令MOV
|
||
|
||
**格式:** MOV dst, src
|
||
|
||
**功能:** 将src的内容传送到dst。
|
||
|
||
**支持的传送方式:**
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| MOV r/m8, r8 | 将8位寄存器传送到8位寄存器/内存 |
|
||
| MOV r/m16, r16 | 将16位寄存器传送到16位寄存器/内存 |
|
||
| MOV r8, r/m8 | 将8位寄存器/内存传送到8位寄存器 |
|
||
| MOV r16, r/m16 | 将16位寄存器/内存传送到16位寄存器 |
|
||
| MOV r/m8, i8 | 将8位立即数传送到8位寄存器/内存 |
|
||
| MOV r/m16, i16 | 将16位立即数传送到16位寄存器/内存 |
|
||
| MOV r8, i8 | 将8位立即数传送到8位寄存器 |
|
||
| MOV r16, i16 | 将16位立即数传送到16位寄存器 |
|
||
| MOV r/m16, sreg | 将段寄存器传送到16位寄存器/内存 |
|
||
| MOV sreg, r/m16 | 将16位寄存器/内存传送到段寄存器 |
|
||
|
||
**注意:** 立即数不能作为dst;不允许直接传送到段寄存器;代码段寄存器CS不能作为dst。
|
||
|
||
### 2. 堆栈操作指令PUSH和POP
|
||
|
||
**格式:**
|
||
```
|
||
PUSH src ;将src压入堆栈
|
||
POP dst ;从堆栈弹出到dst
|
||
```
|
||
|
||
**功能:** PUSH将16位寄存器/内存入栈,POP从堆栈弹出到16位寄存器/内存。
|
||
|
||
**注意:** 必须16位操作;不能压入立即数。
|
||
|
||
### 3. 交换指令XCHG
|
||
|
||
**格式:** XCHG opr1, opr2
|
||
|
||
**功能:** 将两个操作数的内容互换。
|
||
|
||
**支持的传送方式:**
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| XCHG r, r | 两个寄存器互换 |
|
||
| XCHG r, m | 寄存器和内存互换 |
|
||
|
||
### 4. 查表转换指令XLAT
|
||
|
||
**格式:** XLAT
|
||
|
||
**功能:** 将AL中的内容转换为内存表格中某一项的值。即AL←[BX+AL]
|
||
|
||
### 5. 标志传送指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| LAHF | 将标志寄存器低8位传送到AH:AH←FLAGS低8位 |
|
||
| SAHF | 将AH传送到标志寄存器低8位:FLAGS低8位←AH |
|
||
| PUSHF | 将16位标志寄存器压入堆栈:PUSH FLAGS |
|
||
| POPF | 从堆栈弹出到16位标志寄存器:POP FLAGS |
|
||
|
||
### 6. 地址传送指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| LEA r16, src | 将src的有效地址传送到16位寄存器 |
|
||
| LDS r16, src | 将src的段地址传送到DS,有效地址传送到16位寄存器 |
|
||
| LES r16, src | 将src的段地址传送到ES,有效地址传送到16位寄存器 |
|
||
|
||
### 7. 输入输出指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| IN AL, port | 从端口输入一个字节到AL |
|
||
| IN AX, port | 从端口输入一个字到AX |
|
||
| OUT port, AL | 将AL输出到端口 |
|
||
| OUT port, AX | 将AX输出到端口 |
|
||
|
||
**注意:** port为8位立即数表示固定端口;DX表示可变端口(0-65535)。
|
||
|
||
## 二、算术运算指令
|
||
|
||
### 1. 加法指令
|
||
|
||
**(1)ADD指令**
|
||
|
||
格式:ADD dst, src
|
||
|
||
功能:dst←dst+src
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| ADD r/m8, r8 | 8位加法 |
|
||
| ADD r/m16, r16 | 16位加法 |
|
||
| ADD r8, r/m8 | 8位加法 |
|
||
| ADD r16, r/m16 | 16位加法 |
|
||
| ADD r/m8, i8 | 8位加立即数 |
|
||
| ADD r/m16, i16 | 16位加立即数 |
|
||
|
||
**(2)ADC指令**
|
||
|
||
格式:ADC dst, src
|
||
|
||
功能:dst←dst+src+CF(带进位加法)
|
||
|
||
**(3)INC指令**
|
||
|
||
格式:INC opr
|
||
|
||
功能:opr←opr+1(加1)
|
||
|
||
### 2. 减法指令
|
||
|
||
**(1)SUB指令**
|
||
|
||
格式:SUB dst, src
|
||
|
||
功能:dst←dst-src
|
||
|
||
**(2)SBB指令**
|
||
|
||
格式:SBB dst, src
|
||
|
||
功能:dst←dst-src-CF(带借位减法)
|
||
|
||
**(3)DEC指令**
|
||
|
||
格式:DEC opr
|
||
|
||
功能:opr←opr-1(减1)
|
||
|
||
**(4)NEG指令**
|
||
|
||
格式:NEG opr
|
||
|
||
功能:opr←0-opr(求补)
|
||
|
||
### 3. 乘法指令
|
||
|
||
**(1)MUL指令**
|
||
|
||
格式:MUL src
|
||
|
||
功能:
|
||
- 8位:AX←AL*src
|
||
- 16位:DX:AX←AX*src
|
||
|
||
**(2)IMUL指令**
|
||
|
||
格式:IMUL src
|
||
|
||
功能:带符号整数乘法
|
||
|
||
### 4. 除法指令
|
||
|
||
**(1)DIV指令**
|
||
|
||
格式:DIV src
|
||
|
||
功能:
|
||
- 8位:AL←AX/src(商),AH←AX/src(余数)
|
||
- 16位:AX←DX:AX/src(商),DX←DX:AX/src(余数)
|
||
|
||
**(2)IDIV指令**
|
||
|
||
格式:IDIV src
|
||
|
||
功能:带符号整数除法
|
||
|
||
### 5. 十进制调整指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| DAA | 加法后十进制调整 |
|
||
| DAS | 减法后十进制调整 |
|
||
| AAA | 加法后ASCII调整 |
|
||
| AAS | 减法后ASCII调整 |
|
||
| AAM | 乘法后ASCII调整 |
|
||
| AAD | 除法前ASCII调整 |
|
||
|
||
## 三、逻辑运算和移位指令
|
||
|
||
### 1. 逻辑运算指令
|
||
|
||
| 指令 | 功能 |
|
||
|------|------|
|
||
| AND dst, src | 逻辑与 |
|
||
| OR dst, src | 逻辑或 |
|
||
| NOT opr | 逻辑非 |
|
||
| XOR dst, src | 逻辑异或 |
|
||
| TEST opr1, opr2 | 测试(与但不保存结果) |
|
||
|
||
### 2. 移位指令
|
||
|
||
| 指令 | 功能 |
|
||
|------|------|
|
||
| SHL opr, cnt | 逻辑左移 |
|
||
| SAL opr, cnt | 算术左移 |
|
||
| SHR opr, cnt | 逻辑右移 |
|
||
| SAR opr, cnt | 算术右移 |
|
||
| ROL opr, cnt | 循环左移 |
|
||
| ROR opr, cnt | 循环右移 |
|
||
| RCL opr, cnt | 带进位循环左移 |
|
||
| RCR opr, cnt | 带进位循环右移 |
|
||
|
||
**注意:** cnt=1或CL;算术移位保持符号位;循环移位把CF包含在环中。
|
||
|
||
## 四、串操作指令
|
||
|
||
### 1. 基本字符串指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| MOVS dst, src | 移动字节/字串 |
|
||
| MOVSB | 移动字节串 |
|
||
| MOVSW | 移动字串 |
|
||
| CMPS dst, src | 比较字节/字串 |
|
||
| CMPSB | 比较字节串 |
|
||
| CMPSW | 比较字串 |
|
||
| SCAS dst | 扫描字节/字串 |
|
||
| SCASB | 扫描字节串 |
|
||
| SCASW | 扫描字串 |
|
||
| LODS src | 装入字节/字串 |
|
||
| LODSB | 装入字节串 |
|
||
| LODSW | 装入字串 |
|
||
| STOS dst | 存储字节/字串 |
|
||
| STOSB | 存储字节串 |
|
||
| STOSW | 存储字串 |
|
||
|
||
### 2. 串操作指令前缀
|
||
|
||
| 前缀 | 功能 |
|
||
|------|------|
|
||
| REP | 当CX≠0时重复 |
|
||
| REPE/REPZ | 当ZF=1且CX≠0时重复 |
|
||
| REPNE/REPNZ | 当ZF=0且CX≠0时重复 |
|
||
|
||
### 3. 重复前缀的使用
|
||
|
||
```
|
||
;将DS:SI处的100个字节传送到ES:DI处
|
||
CLD
|
||
LEA SI, SOURCE
|
||
LEA DI, DEST
|
||
MOV CX, 100
|
||
REP MOVSB
|
||
```
|
||
|
||
## 五、控制转移指令
|
||
|
||
### 1. 无条件转移指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| JMP target | 无条件转移到目标地址 |
|
||
| CALL target | 调用过程 |
|
||
| RET | 从过程返回 |
|
||
| RETN | 从近过程返回 |
|
||
| RETF | 从远过程返回 |
|
||
|
||
### 2. 条件转移指令
|
||
|
||
**(1)单条件标志转移**
|
||
|
||
| 指令 | 含义 | 测试条件 |
|
||
|------|------|----------|
|
||
| JE/JZ | 等于/为零转移 | ZF=1 |
|
||
| JNE/JNZ | 不等于/非零转移 | ZF=0 |
|
||
| JC | 进位转移 | CF=1 |
|
||
| JNC | 无进位转移 | CF=0 |
|
||
| JO | 溢出转移 | OF=1 |
|
||
| JNO | 无溢出转移 | OF=0 |
|
||
| JS | 符号位为1转移 | SF=1 |
|
||
| JNS | 符号位为0转移 | SF=0 |
|
||
| JP/JPE | 奇偶性为1转移 | PF=1 |
|
||
| JNP/JPO | 奇偶性为0转移 | PF=0 |
|
||
|
||
**(2)无符号数比较转移**
|
||
|
||
| 指令 | 含义 | 测试条件 |
|
||
|------|------|----------|
|
||
| JA/JNBE | 高于/不低于等于转移 | CF=0且ZF=0 |
|
||
| JAE/JNB | 高于或等于/不低于转移 | CF=0 |
|
||
| JB/JNAE | 低于/不高于等于转移 | CF=1 |
|
||
| JBE/JNA | 低于或等于/不高于转移 | CF=1或ZF=1 |
|
||
|
||
**(3)带符号数比较转移**
|
||
|
||
| 指令 | 含义 | 测试条件 |
|
||
|------|------|----------|
|
||
| JG/JNLE | 大于/不小于等于转移 | ZF=0且SF=OF |
|
||
| JGE/JNL | 大于或等于/不小于转移 | SF=OF |
|
||
| JL/JNGE | 小于/不大于等于转移 | SF≠OF |
|
||
| JLE/JNG | 小于或等于/不大于转移 | ZF=1或SF≠OF |
|
||
|
||
### 3. 循环控制指令
|
||
|
||
| 指令 | 操作 | 测试条件 |
|
||
|------|------|----------|
|
||
| LOOP | 循环 | CX≠0 |
|
||
| LOOPE/LOOPZ | 相等/为零循环 | ZF=1且CX≠0 |
|
||
| LOOPNE/LOOPNZ | 不相等/非零循环 | ZF=0且CX≠0 |
|
||
| JCXZ | CX为零转移 | CX=0 |
|
||
|
||
### 4. 中断指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| INT n | 调用中断号n的中断处理程序 |
|
||
| INTO | 溢出中断 |
|
||
| IRET | 中断返回 |
|
||
|
||
## 六、处理器控制指令
|
||
|
||
### 1. 标志操作指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| STC | 进位标志置1:CF←1 |
|
||
| CLC | 进位标志清0:CF←0 |
|
||
| CMC | 进位标志取反:CF←NOT CF |
|
||
| STD | 方向标志置1:DF←1 |
|
||
| CLD | 方向标志清0:DF←0 |
|
||
| STI | 中断允许标志置1:IF←1 |
|
||
| CLI | 中断允许标志清0:IF←0 |
|
||
|
||
### 2. 同步与空操作指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| NOP | 空操作,不执行任何操作 |
|
||
| HLT | 暂停,处理器停止并等待中断或复位信号 |
|
||
| WAIT | 等待,处理器进入等待状态直到BUSREQ有效 |
|
||
| ESC | 换码,用于与协处理器通信 |
|
||
| LOCK | 锁定前缀,禁止其他处理器访问共享内存 |
|
||
|
||
### 3. 段寄存器传送指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| LDS r16, mem32 | 将内存中的32位地址装入DS和寄存器 |
|
||
| LES r16, mem32 | 将内存中的32位地址装入ES和寄存器 |
|
||
| LFS r16, mem32 | 将内存中的32位地址装入FS和寄存器 |
|
||
| LGS r16, mem32 | 将内存中的32位地址装入GS和寄存器 |
|
||
| LSS r16, mem32 | 将内存中的32位地址装入SS和寄存器 |
|
||
|
||
### 4. 转换指令
|
||
|
||
| 指令 | 操作 |
|
||
|------|------|
|
||
| CBW | 将AL中的字节扩展为AX(符号扩展) |
|
||
| CWD | 将AX中的字扩展为DX:AX(符号扩展) |
|
||
| CWDE | 将AX中的字扩展为EAX(符号扩展) |
|
||
| CDQ | 将EAX中的双字扩展为EDX:EAX(符号扩展) |
|
||
| MOVSX r16, r/m8 | 将8位符号扩展为16位 |
|
||
| MOVSX r16, r/m16 | 将16位符号扩展为16位 |
|
||
| MOVSX r32, r/m8 | 将8位符号扩展为32位 |
|
||
| MOVSX r32, r/m16 | 将16位符号扩展为32位 |
|
||
| MOVZX r16, r/m8 | 将8位零扩展为16位 |
|
||
| MOVZX r16, r/m16 | 将16位零扩展为16位 |
|
||
| MOVZX r32, r/m8 | 将8位零扩展为32位 |
|
||
| MOVZX r32, r/m16 | 将16位零扩展为32位 |
|
||
|
||
## 七、伪指令
|
||
|
||
### 1. 数据定义伪指令
|
||
|
||
| 伪指令 | 操作 |
|
||
|--------|------|
|
||
| DB | 定义字节,每个操作数占1字节 |
|
||
| DW | 定义字,每个操作数占2字节 |
|
||
| DD | 定义双字,每个操作数占4字节 |
|
||
| DQ | 定义四字,每个操作数占8字节 |
|
||
| DT | 定义十字节,每个操作数占10字节 |
|
||
|
||
### 2. 段定义伪指令
|
||
|
||
| 伪指令 | 操作 |
|
||
|--------|------|
|
||
| SEGMENT | 定义段的开始 |
|
||
| ENDS | 定义段的结束 |
|
||
| PROC | 定义过程的开始 |
|
||
| ENDP | 定义过程的结束 |
|
||
| ASSUME | 告诉汇编程序段寄存器与段的对应关系 |
|
||
|
||
### 3. 程序结束伪指令
|
||
|
||
| 伪指令 | 操作 |
|
||
|--------|------|
|
||
| END | 表示源程序结束,END后面的标号表示程序入口 |
|
||
| END [标号] | 标记源代码结束 |
|
||
|
||
### 4. 处理器方式伪指令
|
||
|
||
| 伪指令 | 操作 |
|
||
|--------|------|
|
||
| .386 | 允许使用80386指令 |
|
||
| .386P | 允许使用80386保护模式指令 |
|
||
| .8086 | 只允许8086/8088指令(默认) |
|
||
|
||
### 5. 简化段定义伪指令
|
||
|
||
| 伪指令 | 操作 |
|
||
|--------|------|
|
||
| .MODEL | 选择存储模型 |
|
||
| .DATA | 定义数据段 |
|
||
| .CODE | 定义代码段 |
|
||
| .STACK | 定义堆栈段 |
|
||
| PROC | 定义过程 |
|
||
| ENDP | 过程结束 |
|
||
| END | 程序结束 |
|
||
|
||
## 八、寄存器与数据类型
|
||
|
||
### 1. 通用寄存器
|
||
|
||
| 8位寄存器 | 16位寄存器 | 32位寄存器 |
|
||
|-----------|-----------|-----------|
|
||
| AL, AH | AX | EAX |
|
||
| BL, BH | BX | EBX |
|
||
| CL, CH | CX | ECX |
|
||
| DL, DH | DX | EDX |
|
||
| - | SP | ESP |
|
||
| - | BP | EBP |
|
||
| - | SI | ESI |
|
||
| - | DI | EDI |
|
||
|
||
### 2. 段寄存器
|
||
|
||
CS:代码段寄存器
|
||
DS:数据段寄存器
|
||
ES:附加段寄存器
|
||
SS:堆栈段寄存器
|
||
|
||
### 3. 控制寄存器
|
||
|
||
IP:指令指针寄存器
|
||
FLAGS:标志寄存器
|
||
|
||
### 4. 数据类型
|
||
|
||
| 类型 | 大小 |
|
||
|------|------|
|
||
| BYTE | 8位 |
|
||
| WORD | 16位 |
|
||
| DWORD | 32位 |
|
||
| QWORD | 64位 |
|
||
| TBYTE | 80位 |
|
||
|
||
## 九、寻址方式
|
||
|
||
### 1. 立即寻址
|
||
|
||
操作数是立即数,直接包含在指令中。
|
||
|
||
```
|
||
MOV AX, 1234H
|
||
```
|
||
|
||
### 2. 寄存器寻址
|
||
|
||
操作数在寄存器中。
|
||
|
||
```
|
||
MOV AX, BX
|
||
```
|
||
|
||
### 3. 直接寻址
|
||
|
||
操作数的偏移地址直接包含在指令中。
|
||
|
||
```
|
||
MOV AX, [1000H]
|
||
MOV AX, VARIABLE
|
||
```
|
||
|
||
### 4. 寄存器间接寻址
|
||
|
||
操作数的偏移地址在基址寄存器或变址寄存器中。
|
||
|
||
```
|
||
MOV AX, [BX]
|
||
MOV AX, [SI]
|
||
```
|
||
|
||
### 5. 寄存器相对寻址
|
||
|
||
操作数地址=基址/变址寄存器+位移量。
|
||
|
||
```
|
||
MOV AX, [BX+100H]
|
||
MOV AX, [SI+10]
|
||
```
|
||
|
||
### 6. 基址变址寻址
|
||
|
||
操作数地址=基址寄存器+变址寄存器。
|
||
|
||
```
|
||
MOV AX, [BX+SI]
|
||
```
|
||
|
||
### 7. 基址变址相对寻址
|
||
|
||
操作数地址=基址寄存器+变址寄存器+位移量。
|
||
|
||
```
|
||
MOV AX, [BX+SI+10]
|
||
```
|
||
|
||
### 8. 隐含寻址
|
||
|
||
操作数地址隐含在某个寄存器或存储单元中。
|
||
|
||
```
|
||
MUL BL ;AL*BL→AX
|
||
XLAT ;[BX+AL]→AL
|
||
```
|
||
|
||
## 十、常用DOS功能调用
|
||
|
||
### 1. 显示字符串(功能号09H)
|
||
|
||
```
|
||
AH=09H
|
||
DS:DX=字符串地址
|
||
字符串以'$'结尾,需要回车换行时使用0DH、0AH
|
||
```
|
||
|
||
### 2. 输入单个字符(功能号01H)
|
||
|
||
```
|
||
AH=01H
|
||
INT 21H
|
||
;返回:AL=输入字符
|
||
```
|
||
|
||
### 3. 键盘输入字符串(功能号0AH)
|
||
|
||
```
|
||
AH=0AH
|
||
DS:DX=缓冲区地址
|
||
;缓冲区格式:第一个字节=最大字符数,第二个字节=实际字符数,后续=输入字符
|
||
```
|
||
|
||
### 4. 结束程序(功能号4CH)
|
||
|
||
```
|
||
AH=4CH
|
||
AL=返回码
|
||
INT 21H
|
||
```
|
||
|
||
### 5. 显示字符(功能号02H)
|
||
|
||
```
|
||
AH=02H
|
||
DL=字符
|
||
INT 21H
|
||
``` |