938 lines
30 KiB
Markdown
938 lines
30 KiB
Markdown
# 第4章 汇编语言及其程序设计(1-5节)— 期末复习总结
|
||
|
||
---
|
||
|
||
## 一、详细内容分析
|
||
|
||
### 4.1 汇编语言概述
|
||
|
||
#### 基本概念
|
||
|
||
| 术语 | 含义 |
|
||
|------|------|
|
||
| **指令** | 指示计算机完成某种操作的命令 |
|
||
| **程序** | 完成某种功能的指令序列 |
|
||
| **机器语言** | 计算机能直接识别的语言,机器语言写出的程序称为**机器代码** |
|
||
| **汇编语言** | 用字符记号(助记符)代替机器指令的程序,称为**汇编语言源程序** |
|
||
| **汇编程序** | 一个翻译程序,把汇编语言翻译成机器语言(MASM) |
|
||
|
||
#### 汇编语言的运行步骤(汇编语言程序的“上机过程”)
|
||
|
||
```
|
||
编辑程序 (.ASM) → 汇编程序 MASM → 目标程序 (.OBJ) → 连接程序 LINK → 可执行文件 (.EXE)
|
||
```
|
||
|
||
---
|
||
|
||
### 4.2 汇编语言语句格式
|
||
|
||
#### 通用格式
|
||
|
||
```
|
||
[名字/标号] 操作码 [操作数] [;注释]
|
||
```
|
||
|
||
#### 字段含义详解
|
||
|
||
| 字段 | 含义 | 组成 / 规则 |
|
||
|------|------|--------------|
|
||
| **名字(标识符)** | 程序中的符号地址 | 由字母 A~Z、a~z、数字 0~9 及专用符号 `?`、`.`、`@`、`_`、`$` 组成;第一个字符不能是数字;"."若用必须为第一字符;前31字符有效;不能为关键字 |
|
||
| **操作码** | 指令的核心,指定操作类型 | 由 CPU 指令、伪指令、宏指令三类组成 |
|
||
| **操作数** | 参与操作的数据或地址 | 可以有 0、1 或多个 |
|
||
| **注释** | 说明程序或指令功能 | 以分号 `;` 开始,可单独成行 |
|
||
|
||
#### 字段间的分隔符(必考)
|
||
|
||
| 字段间关系 | 分隔符 |
|
||
|-----------|--------|
|
||
| 名字与操作码之间 | 空格或冒号 `:` |
|
||
| 操作码与操作数之间 | 空格 |
|
||
| 多个操作数之间 | 逗号 `,` |
|
||
| 注释开始 | 分号 `;` |
|
||
| 语句之间 | 换行符 |
|
||
|
||
#### 名字的两种类型
|
||
|
||
- **标号**:指令代码的符号地址(用于跳转/调用)
|
||
- **变量**:数据的符号地址
|
||
|
||
---
|
||
|
||
### 4.3 指令格式
|
||
|
||
一条指令由 **5 部分**组成:
|
||
|
||
```
|
||
前缀 操作码 寻址方式 偏移量 立即数
|
||
```
|
||
|
||
#### 指令编码结构(最大 15 字节)
|
||
|
||
| 部分 | 字节数 | 说明 |
|
||
|------|--------|------|
|
||
| **前缀(a)** | 0~3 字节 | 指令前缀、段取代、操作数大小取代、地址大小取代(隐式可共存) |
|
||
| **指令(b)** | 1~12 字节 | 操作码 + MOD/RM + SIB + 偏移量 + 立即数 |
|
||
|
||
MOD/RM 字段含义:
|
||
- **MOD**(2 位):寄存器模式(00/01/10/11)
|
||
- **Reg**(3 位):寄存器编码
|
||
- **R/M**(3 位):寄存器/存储器编码
|
||
|
||
SIB 字段含义:
|
||
- **SS**(2 位):比例因子(00=×1, 01=×2, 10=×4, 11=×8)
|
||
- **变址**(3 位)
|
||
- **基址**(3 位)
|
||
|
||
---
|
||
|
||
### 4.4 寻址方式(**最核心考点**)
|
||
|
||
#### 两类寻址
|
||
|
||
1. **数据寻址**
|
||
2. **转移地址、调用地址寻址**
|
||
|
||
#### 1. 立即寻址
|
||
|
||
- 操作数是**指令的一部分**(随指令一起存放在代码段)。
|
||
- 汇编规定:
|
||
- 立即数必须以**数字开头**;
|
||
- 以字母开头的十六进制数前必须以**数字 0** 做前缀(如 `0AB12H`);
|
||
- 后缀表示进制:**B**=二进制,**H**=十六进制,**D**(或缺省)=十进制,**Q**=八进制。
|
||
- 有符号数以补码表示。
|
||
|
||
```
|
||
MOV AL, 01010101B ; 二进制立即数 01010101B 送 AL
|
||
MOV BX, 0AB12H ; 十六进制立即数 0AB12H(16位)送 BX
|
||
```
|
||
|
||
#### 2. 寄存器寻址
|
||
|
||
- 操作数在 CPU 的某个寄存器中,指令指定寄存器。
|
||
|
||
| 操作数位数 | 可用寄存器 |
|
||
|-----------|------------|
|
||
| 8 位 | AH、AL、BH、BL、CH、CL、DH、DL |
|
||
| 16 位 | AX、BX、CX、DX、SP、BP、SI、DI |
|
||
| 32 位 | EAX、EBX、ECX、EDX、ESP、EBP、EDI、ESI |
|
||
|
||
- 段寄存器寻址:MOV、PUSH、POP 可寻址 16 位的段寄存器(CS、ES、DS、SS、FS、GS)。
|
||
|
||
```
|
||
MOV DS, AX
|
||
MOV DL, BH
|
||
MOV AX, 12
|
||
MOV AL, 12
|
||
```
|
||
|
||
#### 3. 存储器寻址
|
||
|
||
操作数在存储器中。**有效地址 EA** 计算公式:
|
||
|
||
```
|
||
EA = 基址 + (变址 × 比例因子) + 位移量
|
||
```
|
||
|
||
##### 四种成分(16 位 vs 32 位寻址)
|
||
|
||
| 成分 | 16 位寻址 | 32 位寻址 | 作用 |
|
||
|------|----------|----------|------|
|
||
| 位移量 | 0、8、16 位 | 0、8、32 位 | 指令中给出的一个地址类型的数 |
|
||
| 基址寄存器 | BX、BP | 任何 32 位通用寄存器 | 数组或字符串的**首地址** |
|
||
| 变址寄存器 | SI、DI | 除 ESP 外的任何 32 位通用寄存器 | 数组或字符串的**元素索引** |
|
||
| 比例因子 | 无 | 1、2、4、8 | 方便访问不同类型的数据 |
|
||
|
||
**8086 简化公式**:
|
||
|
||
```
|
||
EA = [BX 或 BP] + [SI 或 DI] + [8位位移量 或 16位位移量]
|
||
(每个部分最多保留一项,至少有一项有值)
|
||
```
|
||
|
||
##### 9 种存储器寻址方式总结(重点背诵表)
|
||
|
||
| # | 寻址方式 | 基址 | 变址 | 比例因子 | 位移量 | 举例 |
|
||
|---|---------|-----|-----|---------|-------|------|
|
||
| 1 | 直接寻址 | | | | √ | `MOV BX, [1234H]` |
|
||
| 2 | 寄存器间接寻址 | √* | √* | | | `MOV AL, [BX]` |
|
||
| 3 | 寄存器相对寻址 | √* | √* | | √ | `MOV BX, [SI+40H]` |
|
||
| 4 | 基址变址寻址 | √ | √ | | | `MOV DX, [BX+SI]` |
|
||
| 5 | 相对基址变址寻址 | √ | √ | | √ | `MOV AX, [BP+DI+2]` |
|
||
| 6 | 比例变址寻址 | | √ | √ | | `MOV EAX, [ESI*4]` |
|
||
| 7 | 相对比例变址寻址 | | √ | √ | √ | `MOV EAX, [ESI*4+8]` |
|
||
| 8 | 基址比例变址寻址 | √ | √ | √ | | `MOV EAX, [EBX+ESI*4]` |
|
||
| 9 | 相对基址比例变址寻址 | √ | √ | √ | √ | `MOV EAX, [EBX+ESI*4+8]` |
|
||
|
||
> 注:带 `*` 表示该列只能出现一种(基址或变址任选其一)。
|
||
|
||
##### 段约定和段超越
|
||
|
||
| 存储器操作类型 | 隐含段 | 超越段 | 段内偏移量 | 举例 |
|
||
|--------------|--------|--------|----------|------|
|
||
| 取指令 | CS | 无 | IP | — |
|
||
| 堆栈操作 | SS | 无 | SP | — |
|
||
| 数据变量 | DS | CS、SS、ES | 有效地址 EA | `MOV AL, CS:[1000H]`(从代码段取数据)|
|
||
| 源串变量 | DS | CS、SS、ES | SI | — |
|
||
| 目的串变量 | ES | 无 | DI | — |
|
||
| 基址 BP 指针 | SS | CS、SS、ES | 有效地址 EA | `MOV AL, DS:[BP]`(用 BP 间址访问数据段)|
|
||
|
||
**段约定规则**:使用 BP、SP(EBP、ESP)寻址,默认段为 **SS**;其他通用寄存器参与寻址,默认段为 **DS**。
|
||
|
||
#### 4. 转移地址的寻址方式
|
||
|
||
##### 转移指令分类(段内 / 段间;相对 / 间接;直接 / 间接)
|
||
|
||
```
|
||
段内(修改 IP/EIP) → 相对 / 间接
|
||
段间(修改 CS:IP/EIP)→ 直接 / 间接
|
||
```
|
||
|
||
| 寻址方式 | 含义 |
|
||
|---------|------|
|
||
| **相对寻址** | 给出修改指令指针的一个有符号数(位移量) |
|
||
| **直接寻址** | 目标地址直接给出 |
|
||
| **间接寻址** | 地址在寄存器或存储器中 |
|
||
|
||
##### (1) 段内相对寻址
|
||
|
||
```
|
||
位移量 + IP/EIP = EA → IP/EIP
|
||
```
|
||
|
||
- 位移量是相对值,便于程序重定位。
|
||
- 用于条件转移、无条件转移;**条件转移只能用此方式**。
|
||
- 短跳转:`JMP SHORT A1`,8 位位移量,范围 -128 ~ +127 字节。
|
||
- 近跳转:`JMP NEAR PTR A2`,16/32 位位移量。
|
||
|
||
##### (2) 段内间接寻址
|
||
|
||
```
|
||
寄存器/存储器的内容 = EA → IP/EIP
|
||
```
|
||
|
||
- **不能用于条件转移指令**。
|
||
- 例:`JMP BX`、`JMP WORD PTR [BX+2]`
|
||
|
||
##### (3) 段间直接寻址
|
||
|
||
```
|
||
目标段地址:偏移量 → CS:IP/EIP
|
||
```
|
||
|
||
- 例:`JMP FAR PTR AA6`(远转移,AA6 代表目的地址的逻辑地址)
|
||
|
||
##### (4) 段间间接寻址
|
||
|
||
```
|
||
连续的存储器单元内容 → CS:IP/EIP
|
||
```
|
||
|
||
- DWORD → 段间;WORD → 段内
|
||
- 例:`JMP DWORD PTR [SI]`([SI] 指向的字送 IP,[SI+2] 指向的字送 CS)
|
||
|
||
#### 5. 堆栈地址寻址
|
||
|
||
- 堆栈:"先进后出"工作方式。
|
||
- 80x86 规定:
|
||
1. 堆栈向小地址方向增长。
|
||
2. 必须使用堆栈段,由 SS 给出段基址。
|
||
3. **压入数据时**:先修改指针,再按指针指示的单元存入数据。
|
||
4. **弹出数据时**:先按指针指示的单元取出数据,再修改指针。
|
||
5. 压入/弹出数据类型不同,堆栈指针修改数值不同。
|
||
|
||
---
|
||
|
||
### 4.5 指令系统
|
||
|
||
#### 指令按功能分为 10 类
|
||
|
||
1. 数据传送指令
|
||
2. 算术运算指令
|
||
3. BCD 码调整指令
|
||
4. 逻辑运算指令
|
||
5. 移位循环指令
|
||
6. 控制转移指令
|
||
7. 条件设置指令
|
||
8. 串操作指令
|
||
9. 处理器控制指令
|
||
10. 保护模式系统控制指令
|
||
|
||
**学习要点**:指令的功能、使用的寄存器/存储器单元、影响的标志位、基本应用方法。
|
||
|
||
---
|
||
|
||
#### 4.5.1 数据传送指令(**不影响状态标志**)
|
||
|
||
##### 1. MOV 传送
|
||
|
||
- 格式:`MOV DST, SRC`
|
||
- 功能:`(DST) ← (SRC)`
|
||
- 源、目的操作数长度必须相等。
|
||
- 例:`MOV DS, AX`、`MOV WORD PTR [BX], 10H`
|
||
|
||
##### 2. PUSH 进栈
|
||
|
||
- 格式:`PUSH SRC`
|
||
- 16 位:`(SP) ← (SP) − 2`,`((SP)+1, (SP)) ← (SRC)`
|
||
- 32 位:`(ESP) ← (ESP) − 4`,`((ESP)+3, (ESP)+2, (ESP)+1, (ESP)) ← (SRC)`
|
||
- 可压入:16/32 位通用寄存器、段寄存器、16/32 位存储器(用 PTR 说明)、16/32 位立即数(自 286 以后)。
|
||
|
||
##### 3. POP 出栈
|
||
|
||
- 格式:`POP DST`
|
||
- 与 PUSH 反向,可弹出到寄存器、段寄存器(除 CS 外)、存储器。
|
||
|
||
##### 4. PUSHF / POPF(标志寄存器进/出栈)
|
||
|
||
- 16 位标志寄存器进栈/出栈。
|
||
- PUSHF:标志寄存器低 16 位压入堆栈。
|
||
- POPF:从栈顶弹出 2 个字节送标志寄存器低 16 位。
|
||
|
||
##### 5. XCHG 交换
|
||
|
||
- 格式:`XCHG OPR1, OPR2`
|
||
- 功能:`(OPR1) ↔ (OPR2)`
|
||
- 类型:存储器与通用寄存器之间、寄存器与寄存器之间。
|
||
|
||
##### 6. LEA 有效地址送寄存器
|
||
|
||
- 格式:`LEA REG, SRC`
|
||
- 功能:`(REG) ← (SRC)` 的有效地址
|
||
- **注意**:LEA 取的是**有效地址(偏移量)**,MOV 取的是**地址中的内容**。
|
||
- 例:
|
||
```
|
||
MOV AX, 2000H
|
||
MOV DS, AX
|
||
MOV BX, 3000H
|
||
MOV AX, [BX+102H] ; (AX) = 7856H(取内容)
|
||
LEA SI, [BX+102H] ; (SI) = 3102H(取偏移地址)
|
||
```
|
||
|
||
##### 7. LDS、LES、LFS、LGS、LSS 指针送寄存器和段寄存器
|
||
|
||
- 格式:`LDS REG, SRC`
|
||
- 功能:`(REG) ← [SRC]`,`(DS) ← [SRC+2]`(16 位 EA),`(DS) ← [SRC+4]`(32 位 EA)
|
||
- 例:已知 (DS)=5100H, (BX)=2000H,执行 `LDS DI, [BX]` 后:
|
||
- (DI) = 2211H(高地址 22H,低地址 11H 组成)
|
||
- (DS) = 4433H
|
||
|
||
##### 8. XLAT 换码
|
||
|
||
- 格式:`XLAT`(无操作数)
|
||
- 功能:`AL ← [BX+AL]`(16 位指令)或 `AL ← [EBX+AL]`(32 位指令)
|
||
- 偏移量 8 位,表长 ≤ 256。
|
||
- 用途:代码转换(如 BCD→ASCII)。
|
||
- 例:已知 (DS)=5000H, (BX)=4000H, (AL)=09H,5000:4000H 开始存储数字 ASCII 转换表,执行 XLAT 后 AL=39H。
|
||
|
||
##### 9. IN/OUT 输入/输出(不需要段地址)
|
||
|
||
| 类型 | IN 输入 | OUT 输出 |
|
||
|------|--------|---------|
|
||
| 直接寻址(端口地址 n ≤ 255) | `IN AL, n` | `OUT n, AL` |
|
||
| 间接寻址(端口地址在 DX 中) | `IN AL, DX` | `OUT DX, AL` |
|
||
|
||
```
|
||
IN AL, 88H
|
||
MOV DX, 88H
|
||
IN AL, DX ; 全部端口地址可用
|
||
```
|
||
|
||
---
|
||
|
||
#### 4.5.2 算术运算指令
|
||
|
||
##### 1. 加法、减法指令
|
||
|
||
**(1) ADD 加法**
|
||
|
||
- 格式:`ADD DST, SRC`
|
||
- 功能:`(DST) ← (SRC) + (DST)`
|
||
- 影响标志位:**CF、PF、AF、ZF、SF、OF**
|
||
- 可进行 8、16、32 位操作。
|
||
- 源、目不能同时为存储器。
|
||
|
||
**(2) ADC 带进位加法**
|
||
|
||
- 格式:`ADC DST, SRC`
|
||
- 功能:`(DST) ← (SRC) + (DST) + CF`
|
||
- 用于多字节加法。
|
||
|
||
**(3) SUB 减法**
|
||
|
||
- 格式:`SUB DST, SRC`
|
||
- 功能:`(DST) ← (DST) − (SRC)`
|
||
|
||
**(4) SBB 带借位减法**
|
||
|
||
- 格式:`SBB DST, SRC`
|
||
- 功能:`(DST) ← (DST) − (SRC) − CF`
|
||
|
||
**例题**:
|
||
```
|
||
MOV AX, 7626H
|
||
MOV BX, 6615H
|
||
ADD AX, BX ; (AX) = 0DC3BH
|
||
```
|
||
- CF=? PF=? AF=? ZF=? SF=? OF=?
|
||
|
||
##### 2. 加 1、减 1 指令
|
||
|
||
- `INC OPR`:`(OPR) ← (OPR) + 1`
|
||
- `DEC OPR`:`(OPR) ← (OPR) − 1`
|
||
- 影响 AF、OF、PF、SF、ZF,**但不影响 CF**。
|
||
- 操作数可为通用寄存器、存储器单元;8/16/32 位均可。
|
||
|
||
##### 3. CMP 比较
|
||
|
||
- 格式:`CMP OPR1, OPR2`
|
||
- 功能:`(OPR1) − (OPR2)`,**不改变源和目的操作数**,按减法规则影响标志位。
|
||
- 用途:为条件转移指令提供依据。
|
||
|
||
##### 4. MUL 无符号数乘法
|
||
|
||
| 操作数 | 隐含被乘数 | 结果存放 |
|
||
|--------|-----------|---------|
|
||
| 字节乘 | AL | AX ← AL × SRC |
|
||
| 字乘 | AX | DX:AX ← AX × SRC |
|
||
| 双字乘 | EAX | EDX:EAX ← EAX × SRC |
|
||
|
||
- 两操作数指令,一个隐含在累加器。
|
||
- 若乘积高半部为 0,则 CF=0、OF=0;否则 CF=1、OF=1。
|
||
- AF、PF、ZF、SF 无定义。
|
||
|
||
##### 5. DIV 无符号数除法
|
||
|
||
- 格式:`DIV SRC`
|
||
- 字节除:(AL) ← (AX)/(SRC) 的商,(AH) ← 余数
|
||
- 字除:(AX) ← (DX:AX)/(SRC) 的商,(DX) ← 余数
|
||
- 双字除:(EAX) ← (EDX:EAX)/(SRC) 的商,(EDX) ← 余数
|
||
- 被除数默认在 AX、DX:AX 或 EDX:EAX 中;所有标志位无定义。
|
||
|
||
---
|
||
|
||
#### 4.5.3 BCD 码调整指令
|
||
|
||
##### 1. DAA 压缩 BCD 码加法调整(只对 AL 调整)
|
||
|
||
- 与 ADD、ADC 结合,完成十进制加法。
|
||
- 规则:
|
||
1. 若 AL 的低 4 位 > 9 或 AF=1,则 `(AL) + 6 → (AL)`,并 `1 → AF`;
|
||
2. 若 AL 的高 4 位 > 9 或 CF=1,则 `(AL) + 60H → (AL)`,并 `1 → CF`。
|
||
- 影响除 OF 外的 5 个标志位。
|
||
|
||
**例**:
|
||
```
|
||
MOV AL, 54H ; 54H 代表十进制数 54
|
||
MOV BL, 37H ; 37H 代表十进制数 37
|
||
ADD AL, BL ; AL = 8BH(十六进制和)
|
||
DAA ; AL = 91H,AF=1, CF=0;十进制加法为 91
|
||
```
|
||
|
||
##### 2. DAS 压缩 BCD 码减法调整
|
||
|
||
- 与 SUB、SBB 结合,完成十进制减法。
|
||
- 规则类似 DAA,用减 6 / 减 60H。
|
||
|
||
##### 3. AAA 非压缩 BCD 码加法调整
|
||
|
||
- 规则:
|
||
1. 若 AL 的低 4 位 ≤ 9 且 AF=0,跳转步骤 ③;
|
||
2. `(AL) + 6 → AL`,`1 → AF`,`(AH) + 1 → AH`;
|
||
3. AL 高 4 位清 0;
|
||
4. `AF → CF`。
|
||
- 影响 AF、CF;PF、SF、ZF、OF 无定义。
|
||
|
||
---
|
||
|
||
#### 4.5.4 逻辑运算指令(按位进行运算)
|
||
|
||
##### 1. 与、或、异或、比较
|
||
|
||
| 指令 | 格式 | 功能 |
|
||
|------|------|------|
|
||
| AND | `AND DST, SRC` | `(DST) ← (DST) ∧ (SRC)` |
|
||
| OR | `OR DST, SRC` | `(DST) ← (DST) ∨ (SRC)` |
|
||
| XOR | `XOR DST, SRC` | `(DST) ← (DST) ⊕ (SRC)` |
|
||
| TEST | `TEST OPR1, OPR2` | `(OPR1) ∧ (OPR2)`,结果**不保存**,只影响标志位 |
|
||
|
||
- CF、OF **置 0**,影响 SF、ZF、PF,AF 无定义。
|
||
- TEST 与 AND 一样运算和影响标志位,但结果不保存。
|
||
|
||
**例**:
|
||
```
|
||
MOV AL, 12H
|
||
AND AL, 0FH ; (AL) = 02H(保留低 4 位)
|
||
OR AL, 30H ; (AL) = 32H(高 4 位变为 0011)
|
||
```
|
||
|
||
##### 2. NOT 按位取反
|
||
|
||
- 格式:`NOT OPR`
|
||
- 功能:`(OPR) ← ¬(OPR)`,每一位取反。
|
||
- **不影响标志位**。
|
||
- 操作数 8/16/32 位均可。
|
||
|
||
---
|
||
|
||
#### 4.5.5 移位循环指令
|
||
|
||
##### 1. 移位指令
|
||
|
||
| 指令 | 格式 | 功能说明 |
|
||
|------|------|---------|
|
||
| **SHL** 逻辑左移 | `SHL OPR, CNT` | 左移,最低位补 0,最高位 → CF |
|
||
| **SHR** 逻辑右移 | `SHR OPR, CNT` | 右移,最高位补 0,最低位 → CF |
|
||
| **SAL** 算术左移 | `SAL OPR, CNT` | 与 SHL 相同(高 8 位/16 位/32 位操作) |
|
||
| **SAR** 算术右移 | `SAR OPR, CNT` | 右移,最高位不变(保持符号),最低位 → CF |
|
||
|
||
- CNT:8 位立即数(1~31,8086 中只能为 1)或 CL。
|
||
- CF 依操作设置;OF 当 CNT=1 时有效(若最高位产生变化则置 1)。
|
||
|
||
##### 2. 循环指令
|
||
|
||
| 指令 | 格式 | 功能 |
|
||
|------|------|------|
|
||
| **ROL** 循环左移 | `ROL OPR, CNT` | 不带 CF 的循环左移 |
|
||
| **ROR** 循环右移 | `ROR OPR, CNT` | 不带 CF 的循环右移 |
|
||
| **RCL** 带进位循环左移 | `RCL OPR, CNT` | 带 CF 的循环左移(共 9/17/33 位) |
|
||
| **RCR** 带进位循环右移 | `RCR OPR, CNT` | 带 CF 的循环右移 |
|
||
|
||
---
|
||
|
||
#### 4.5.6 控制转移指令
|
||
|
||
##### 1. 无条件段内相对短转移
|
||
|
||
- 格式:`JMP SHORT OPR`
|
||
- 功能:`(IP) ← (IP) + 8 位位移量`(范围 -128 ~ +127 字节)
|
||
|
||
##### 2. 无条件段内相对近转移
|
||
|
||
- 格式:`JMP NEAR PTR OPR`
|
||
- 功能:`(IP) ← (IP) + 16/32 位位移量`
|
||
|
||
##### 3. 无条件段内间接转移
|
||
|
||
- 格式:`JMP OPR`,OPR 可为寄存器、存储器
|
||
- 功能:`(IP) ← (EA)` 或 `(EIP) ← (EA)`
|
||
- 例:`JMP BX`
|
||
|
||
##### 4. 无条件段间直接转移
|
||
|
||
- 格式:`JMP FAR PTR OPR`
|
||
- 功能:`(IP/EIP) ← OPR 的段内偏移地址`,`(CS) ← OPR 所在段的段地址`
|
||
|
||
##### 5. 无条件段间间接转移
|
||
|
||
- 格式:`JMP DWORD PTR OPR`
|
||
- 功能:`(IP/EIP) ← [EA]`,`(CS) ← [EA+2] 或 [EA+4]`
|
||
|
||
**注意区别**:无条件/条件;绝对/相对;段内/段间;短转移/近转移/远转移。
|
||
|
||
##### 6. 条件相对转移(**全部为短转移**)
|
||
|
||
**(1) 单条件相对转移**
|
||
|
||
| 指令 | 转移条件 | 含义 |
|
||
|------|---------|------|
|
||
| JZ / JE | ZF=1 | 结果为零或相等 |
|
||
| JNZ / JNE | ZF=0 | 结果不为零或不相等 |
|
||
| JS | SF=1 | 结果为负 |
|
||
| JNS | SF=0 | 结果为正 |
|
||
| JO | OF=1 | 结果溢出 |
|
||
| JNO | OF=0 | 结果不溢出 |
|
||
| JP / JPE | PF=1 | 结果为偶 |
|
||
| JNP / JPO | PF=0 | 结果为奇 |
|
||
| JC | CF=1 | 有借位或有进位 |
|
||
| JNC | CF=0 | 无借位或无进位 |
|
||
|
||
**指令操作码字母含义**:
|
||
|
||
| 字母 | 含义 |
|
||
|------|------|
|
||
| J | jump(跳转) |
|
||
| Z | zero(零) |
|
||
| E | equal(相等) |
|
||
| N | not(不) |
|
||
| S | sign(符号) |
|
||
| P | parity(奇偶) |
|
||
| C | carry(进位) |
|
||
| O | overflow(溢出) |
|
||
| PE | parity even(偶校验) |
|
||
| PO | parity odd(奇校验) |
|
||
|
||
**(2) 无符号数比较条件相对转移(A−B,A:above 高于,B:below 低于)**
|
||
|
||
| 指令 | 转移条件 | 含义 |
|
||
|------|---------|------|
|
||
| JB / JNAE / JC | CF=1 | A < B |
|
||
| JAE / JNB / JNC | CF=0 | A ≥ B |
|
||
| JBE / JNA | (CF∨ZF)=1 | A ≤ B |
|
||
| JA / JNBE | (CF∨ZF)=0 | A > B |
|
||
|
||
**(3) 有符号数比较条件相对转移(A−B,G:greater 大于,L:less 小于)**
|
||
|
||
| 指令 | 转移条件 | 含义 |
|
||
|------|---------|------|
|
||
| JL / JNGE | (SF⊕OF)=1 | A < B |
|
||
| JGE / JNL | (SF⊕OF)=0 | A ≥ B |
|
||
| JLE / JNG | ((SF⊕OF)∨ZF)=1 | A ≤ B |
|
||
| JG / JNLE | ((SF⊕OF)∨ZF)=0 | A > B |
|
||
|
||
**例**:
|
||
```
|
||
MOV AL, 80H
|
||
CMP AL, BL
|
||
JC L ; 若有进位(即 A<B),转 L
|
||
```
|
||
|
||
##### 7. LOOP 循环控制相对转移
|
||
|
||
- 格式:`LOOP OPR`
|
||
- 功能:`(CX/ECX) ← (CX/ECX) − 1`;若 `(CX/ECX) ≠ 0`,则转移。
|
||
- 转移地址为 `(IP/EIP) ← (IP/EIP) + 8 位带符号数`。
|
||
- **CX 必须预先装入循环次数**。
|
||
|
||
```
|
||
MOV CX, 64H ; 循环 100 次
|
||
L: ......
|
||
......
|
||
LOOP L
|
||
```
|
||
|
||
##### 8. 子程序调用与返回
|
||
|
||
子程序:具有独立功能的程序模块。
|
||
|
||
**(1) 段内相对调用 `CALL NEAR PTR DST`**
|
||
|
||
```
|
||
16 位:SP ← (SP)−2,[SP] ← (IP);IP ← (IP)+16 位位移量
|
||
32 位:ESP ← (ESP)−4,[ESP] ← (EIP);EIP ← (EIP)+32 位位移量
|
||
```
|
||
|
||
**(2) 段内间接调用 `CALL DST`**(DST 为 R、M)
|
||
|
||
```
|
||
16 位:SP ← (SP)−2,[SP] ← (IP);(IP) ← (EA)
|
||
32 位:ESP ← (ESP)−4,[ESP] ← (EIP);(EIP) ← (EA)
|
||
```
|
||
|
||
**(3) 段间直接调用**
|
||
|
||
- 16 位:依次压入 CS、IP,再转向 DST。
|
||
- 说明:先将 CS、IP 或 EIP 压栈保护返回地址,然后转移到 DST 指定的转移地址。
|
||
|
||
**(4) 段间间接调用**
|
||
|
||
- 16 位:`IP ← (EA)`,`CS ← (EA+2)`
|
||
- 32 位:`EIP ← (EA)`,`CS ← (EA+4)`
|
||
|
||
**(5) 段内返回 RET**
|
||
|
||
- 16 位:`IP ← 栈弹出 2 字节,SP ← (SP)+2`
|
||
- 32 位:`EIP ← 栈弹出 4 字节,ESP ← (ESP)+4`
|
||
|
||
**(6) 段内带参数返回 `RET N`**
|
||
|
||
- 弹出返回地址后,`SP ← (SP)+N`,用于清除堆栈中的参数。
|
||
- N 是 16 位常数(偶数)。
|
||
|
||
**(7) 段间返回 RET**
|
||
|
||
- 不仅恢复断点的偏移地址,还要恢复段地址。
|
||
- 16 位:弹出 IP、CS;32 位:弹出 EIP、CS。
|
||
|
||
**(8) 段间带参数返回 `RET N`**
|
||
|
||
- 段间返回 + SP += N。
|
||
|
||
##### 9. 中断指令
|
||
|
||
- **中断向量地址 = 中断类型码 × 4**
|
||
|
||
**(1) INT 中断指令**
|
||
|
||
- 格式:`INT n`,n 为类型码(8 位无符号数),**不影响标志位**。
|
||
- 功能步骤(10 步):
|
||
1. SP ← (SP) − 2
|
||
2. **PUSH (FR)**:标志寄存器 FR 进栈
|
||
3. SP ← (SP) − 2
|
||
4. **PUSH (CS)**:断点段地址 CS 进栈
|
||
5. SP ← (SP) − 2
|
||
6. **PUSH (IP)**:断点地址指针 IP 进栈
|
||
7. **TF ← 0**:禁止单步
|
||
8. **IF ← 0**:禁止中断
|
||
9. **IP ← [n × 4]**:转向中断服务程序
|
||
10. **CS ← [n × 4 + 2]**
|
||
|
||
**(2) IRET 中断返回**(中断服务程序最后一条指令)
|
||
|
||
- 步骤(6 步):
|
||
1. IP ← 栈弹出 2 字节(断点偏移量出栈)
|
||
2. SP ← (SP) + 2
|
||
3. CS ← 栈弹出 2 字节(断点段地址出栈)
|
||
4. SP ← (SP) + 2
|
||
5. FR ← 栈弹出 2 字节(标志寄存器出栈)
|
||
6. SP ← (SP) + 2
|
||
- 标志位随标志寄存器出栈操作而改变。
|
||
|
||
**(3) INT 21H 系统功能调用**
|
||
|
||
- 系统功能调用:DOS 为系统程序员及用户提供的一组中断服务程序。
|
||
- DOS 规定用 INT 21H 作为进入各功能调用中断服务程序的总入口。
|
||
- **使用过程**:
|
||
1. AH ← 功能号
|
||
2. 设置入口参数
|
||
3. CPU 执行 INT 21H
|
||
4. 读取出口参数
|
||
|
||
| 功能号 | 作用 | 调用方式 |
|
||
|--------|------|---------|
|
||
| **1** | 等待键盘输入,并回送显示器 | `MOV AH, 1`;`INT 21H`;出口 (AL) = 键入字符 ASCII 码 |
|
||
| **2** | 输出字符送显示器 | `MOV DL, 41H`;`MOV AH, 2`;`INT 21H`(显示 A)|
|
||
| **4CH** | 终止程序,返回 | `MOV AH, 4CH`;`INT 21H` |
|
||
|
||
---
|
||
|
||
#### 4.5.7 串操作指令(提示:详见后续章节)
|
||
|
||
- 主要串操作指令:MOVS、STOS、LODS、CMPS、SCAS 等。
|
||
- 串操作方向由 **DF 标志**控制:
|
||
- `CLD`:DF ← 0,串操作地址递增。
|
||
- `STD`:DF ← 1,串操作地址递减。
|
||
|
||
---
|
||
|
||
#### 4.5.8 处理器控制指令(标志处理指令)
|
||
|
||
标志处理指令只设置或清除本指令的标志位,而不影响其他标志位。
|
||
|
||
| 指令 | 功能 | 说明 |
|
||
|------|------|------|
|
||
| **CLC** | CF ← 0 | clear carry(进位位置 0)|
|
||
| **STC** | CF ← 1 | set carry(进位位置 1)|
|
||
| **CLD** | DF ← 0 | clear direction(方向标志置 0)|
|
||
| **STD** | DF ← 1 | set direction(方向标志置 1)|
|
||
| **CLI** | IF ← 0 | clear interrupt(禁止中断)|
|
||
| **STI** | IF ← 1 | set interrupt(允许中断)|
|
||
| **NOP** | 空操作 | 不执行任何操作 |
|
||
| **HLT** | 暂停 | 退出暂停方式:中断、硬件复位、DMA 操作 |
|
||
|
||
---
|
||
|
||
### 补充:汇编伪指令(用于组织源程序)
|
||
|
||
> 本章 PPT 主要涉及指令系统,但考试常考伪指令含义。
|
||
|
||
| 伪指令 | 作用 |
|
||
|--------|------|
|
||
| **DB** (Define Byte) | 定义字节数据 |
|
||
| **DW** (Define Word) | 定义字数据 |
|
||
| **DD** (Define Doubleword) | 定义双字数据 |
|
||
| **EQU** | 等值伪指令,给符号赋值 |
|
||
| **SEGMENT / ENDS** | 定义段的开始和结束 |
|
||
| **ASSUME** | 设定段寄存器与段的对应关系 |
|
||
| **PROC / ENDP** | 定义子程序(过程)的开始和结束 |
|
||
| **END** | 源程序结束标志 |
|
||
| **OFFSET** | 取偏移地址 |
|
||
| **PTR** | 指定操作数类型(BYTE/WORD/DWORD)|
|
||
|
||
**子程序参数传递的三种方式**(汇编核心考点):
|
||
|
||
| 方式 | 优点 | 缺点 |
|
||
|------|------|------|
|
||
| **寄存器传递** | 简单快速 | 寄存器数量有限 |
|
||
| **堆栈传递** | 参数数量灵活 | 需注意栈平衡(RET N)|
|
||
| **存储器传递** | 可传递大量数据 | 需约定共享存储区 |
|
||
|
||
**段寄存器与段对应关系(ASSUME 用法)**:
|
||
```
|
||
DATA SEGMENT
|
||
X DB 12H
|
||
DATA ENDS
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX ; DS 装载数据段地址
|
||
MOV AL, X
|
||
...
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
---
|
||
|
||
### 标志位(FLAGS)总览
|
||
|
||
| 标志位 | 名称 | 说明 | 受哪些指令影响 |
|
||
|--------|------|------|--------------|
|
||
| **CF** | Carry Flag(进位标志) | 无符号数溢出 | ADD、SUB、MUL、DIV、SHL、SHR、CMP、CLC/STC |
|
||
| **PF** | Parity Flag(奇偶标志) | 结果低 8 位中"1"的个数为偶数 | ADD、SUB、AND、OR、XOR、TEST、CMP |
|
||
| **AF** | Auxiliary Carry(辅助进位) | 第 3 位向第 4 位有进/借位 | ADD、SUB、DAA、DAS、AAA |
|
||
| **ZF** | Zero Flag(零标志) | 结果为零 | ADD、SUB、AND、OR、XOR、CMP、TEST、INC/DEC |
|
||
| **SF** | Sign Flag(符号标志) | 结果最高位为 1 | 大多数算术/逻辑指令 |
|
||
| **OF** | Overflow Flag(溢出标志) | 有符号数溢出 | ADD、SUB、CMP、SHL/SAR、INC/DEC、MUL |
|
||
| **DF** | Direction Flag(方向标志) | 串操作方向 | CLD/STD |
|
||
| **IF** | Interrupt Flag(中断标志) | 是否允许中断 | CLI/STI |
|
||
| **TF** | Trap Flag(单步标志) | 单步调试 | 无(专用)|
|
||
|
||
---
|
||
|
||
## 二、考点总结(考试重点)
|
||
|
||
### 【高频】1. 寻址方式(必考)
|
||
|
||
- **【高频】** 7/8 种寻址方式及例题判别:
|
||
- 立即寻址 vs 直接寻址:`MOV AX, 1234H` vs `MOV AX, [1234H]`
|
||
- 寄存器寻址 vs 寄存器间接寻址:`MOV AX, BX` vs `MOV AX, [BX]`
|
||
- 寄存器相对寻址:`MOV AX, [BX+10H]`
|
||
- 基址变址寻址:`MOV AX, [BX+SI]`
|
||
- 相对基址变址寻址:`MOV AX, [BX+SI+10H]`
|
||
|
||
### 【高频】2. 指令格式
|
||
|
||
- 【高频】指令格式:`[标号:] 操作码 [操作数] [;注释]`
|
||
- 4 个字段、分隔符规则、标识符规则(首字符不能为数字、31 字符有效、不能为关键字等)
|
||
|
||
### 【高频】3. 伪指令含义
|
||
|
||
- 【高频】DB、DW、DD、EQU、SEGMENT/ENDS、ASSUME、PROC/ENDP、END、OFFSET、PTR 的含义与用法
|
||
|
||
### 【高频】4. 常用指令功能
|
||
|
||
- 【高频】MOV、PUSH/POP、ADD/SUB、MUL/DIV、AND/OR/XOR、CMP、TEST、SHL/SHR、SAL/SAR、ROL/ROR/RCL/RCR、JMP/JCC、LOOP、CALL/RET、INT n
|
||
|
||
### 【高频】5. 标志位影响
|
||
|
||
- 【高频】哪些指令影响哪些标志位(尤其是 INC/DEC 不影响 CF;NOT 不影响标志位;MUL/DIV 部分标志位无定义;逻辑指令使 CF=OF=0)
|
||
|
||
### 【高频】6. 子程序调用过程
|
||
|
||
- 【高频】CALL/RET 指令执行过程(断点保护、参数弹出、栈平衡)
|
||
|
||
### 【高频】7. 参数传递方式
|
||
|
||
- 【高频】子程序参数传递三种方式:寄存器、堆栈、存储器
|
||
|
||
### 【高频】8. 循环指令 LOOP
|
||
|
||
- 【高频】LOOP 指令使用前提:CX 必须预装循环次数;CX 自动 −1,非 0 则循环
|
||
|
||
### 9. 其他重点
|
||
|
||
- 段约定规则(BP 用 SS,其他用 DS)
|
||
- 堆栈操作(PUSH 先改指针再存,POP 先取数据再改指针)
|
||
- 条件转移指令:操作码字母含义、单条件 vs 无符号数比较 vs 有符号数比较
|
||
- INT 21H 系统功能调用(1 号、2 号、4CH 号功能)
|
||
- 8086 与 32 位寻址方式的区别
|
||
- 段内 vs 段间转移;短/近/远转移;相对 vs 绝对 vs 间接寻址
|
||
- LEA 与 MOV 的区别
|
||
- BCD 码调整指令(DAA、DAS、AAA)的使用条件
|
||
- LEA、PTR、OFFSET 的区别
|
||
|
||
---
|
||
|
||
### 常见题型
|
||
|
||
#### 题型 1:读程序写结果(**最常考**)
|
||
|
||
- 给定指令序列,求寄存器值、标志位值、存储器内容。
|
||
- 例:已知 (AX)=7626H, (BX)=6615H,执行 ADD AX, BX 后求 (AX) 及 CF/PF/AF/ZF/SF/OF。
|
||
|
||
#### 题型 2:寻址方式判断
|
||
|
||
- 给出 MOV、JMP、CALL 等指令,问属于哪种寻址方式。
|
||
- 例:`MOV AX, [BX+SI+10H]` 属于哪种寻址?(答:相对基址变址寻址)
|
||
|
||
#### 题型 3:程序填空
|
||
|
||
- 给定功能(如求和、统计字符、传送数据块),写出汇编片段。
|
||
- 例:编写把数据段中 N 个字节数据求和的程序段。
|
||
|
||
#### 题型 4:子程序设计与参数传递分析
|
||
|
||
- 设计带参数子程序,分析调用前后寄存器/堆栈/存储器的变化。
|
||
- 例:编写一个求数组最大值的子程序,用寄存器、堆栈或存储器方式传递参数。
|
||
|
||
#### 题型 5:标志位判断
|
||
|
||
- 给定运算结果,判断 6 个状态标志位(CF、PF、AF、ZF、SF、OF)。
|
||
|
||
#### 题型 6:BCD 码转换
|
||
|
||
- 给定 ADD AL, BL 后执行 DAA,求 AL 及 AF、CF。
|
||
|
||
#### 题型 7:中断与功能调用
|
||
|
||
- 分析 INT n、INT 21H 的执行过程(压栈顺序、转向地址)。
|
||
|
||
#### 题型 8:综合程序阅读
|
||
|
||
- 给定一段完整程序(含段定义、子程序调用、循环、条件转移),写出执行结果。
|
||
|
||
---
|
||
|
||
### 易错点提示
|
||
|
||
1. **MOV 与 LEA 的区别**:MOV 取内容,LEA 取偏移地址。
|
||
2. **INC/DEC 不影响 CF**,但影响其他标志位。
|
||
3. **NOT 不影响标志位**(与 INC/DEC/NEG 不同)。
|
||
4. **逻辑指令使 CF = OF = 0**(AND/OR/XOR/TEST)。
|
||
5. **MUL/DIV 中 AF、PF、ZF、SF 无定义**。
|
||
6. **条件转移只能用相对寻址**。
|
||
7. **段内间接寻址不能用于条件转移**。
|
||
8. **PUSH 段寄存器不包括 CS 直接压入**(但 CALL 段间调用会自动压 CS)。
|
||
9. **LOOP 指令默认操作数是 CX**(32 位是 ECX)。
|
||
10. **XLAT 表长 ≤ 256**,偏移量 8 位。
|
||
11. **CMP 不保存结果**,只影响标志位。
|
||
12. **TEST 不保存结果**,只影响标志位(同 CMP)。
|
||
|
||
---
|
||
|
||
### 关键英文缩写速查
|
||
|
||
| 缩写 | 全称 | 含义 |
|
||
|------|------|------|
|
||
| MOV | Move | 数据传送 |
|
||
| ADD/SUB | Add/Subtract | 加/减 |
|
||
| MUL/DIV | Multiply/Divide | 乘/除 |
|
||
| INC/DEC | Increment/Decrement | 加 1/减 1 |
|
||
| CMP | Compare | 比较 |
|
||
| JMP | Jump | 跳转 |
|
||
| JCC | Jump Conditional | 条件跳转 |
|
||
| LOOP | Loop | 循环 |
|
||
| CALL/RET | Call/Return | 调用/返回 |
|
||
| INT | Interrupt | 中断 |
|
||
| PUSH/POP | Push/Pop | 压栈/出栈 |
|
||
| IN/OUT | Input/Output | 输入/输出 |
|
||
| SHL/SHR | Shift Left/Right (Logical) | 逻辑左/右移 |
|
||
| SAL/SAR | Shift Arithmetic Left/Right | 算术左/右移 |
|
||
| ROL/ROR | Rotate Left/Right | 循环左/右移 |
|
||
| RCL/RCR | Rotate with Carry Left/Right | 带进位循环左/右移 |
|
||
| AND/OR/XOR | And/Or/Exclusive Or | 逻辑与/或/异或 |
|
||
| TEST | Test | 测试 |
|
||
| NOT | Not | 取反 |
|
||
| XLAT | Translate | 换码 |
|
||
| LEA | Load Effective Address | 取有效地址 |
|
||
| LDS/LES | Load DS/ES (and register) | 装入段寄存器 |
|
||
| DAA/DAS | Decimal Adjust for Addition/Subtraction | 十进制加/减调整 |
|
||
| AAA | ASCII Adjust for Addition | ASCII 加法调整 |
|
||
| CLC/STC | Clear/Set Carry Flag | 清/置进位 |
|
||
| CLD/STD | Clear/Set Direction Flag | 清/置方向 |
|
||
| CLI/STI | Clear/Set Interrupt Flag | 清/置中断 |
|
||
| NOP | No Operation | 空操作 |
|
||
| HLT | Halt | 暂停 |
|
||
| IRET | Interrupt Return | 中断返回 |
|
||
|
||
---
|
||
|
||
**考试小贴士**:
|
||
|
||
1. 必背寻址方式表(9 种),重点是 16 位下的 5 种基本寻址。
|
||
2. 必背条件转移指令表(单条件、无符号比较、有符号比较)。
|
||
3. 必背标志位影响表。
|
||
4. 必背汇编语句格式及 4 个字段。
|
||
5. 必背 PUSH/POP、CALL/RET 的执行过程(堆栈变化)。
|
||
6. 注意区分"MOV 内存, 立即数"时需用 PTR 说明长度。 |