Files
Operating-System/Experiment/asm-exp/实验四/实验四_循环程序设计.md
2026-06-25 00:09:09 +08:00

274 lines
8.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 实验四:循环程序设计
## 一、实验目的
1. 掌握循环程序的基本结构和设计方法
2. 理解LOOP指令的工作原理和使用方法
3. 掌握多重循环程序的设计技术
4. 理解循环计数器的作用和设置方法
---
## 二、基础性实验
### 实验4_1 循环结构一:求累加和
#### 实验目的
掌握利用LOOP指令实现循环程序的设计方法。
#### 实验内容
利用循环程序求1+2+3+...+10的和。
#### 程序代码
```asm
DATAS SEGMENT
LIST DB 01H,02H,03H,04H,05H,06H,07H,08H,09H,0AH
COUNT EQU 10
RESULT DB ?
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
LEA SI, LIST ; SI指向数据表首地址
MOV CX, COUNT ; 设置循环计数初值
XOR BL, BL ; BL清0累加和初值为0
XOR BH, BH ; BH清0
L1:
MOV AL, [SI] ; 取出数据
ADD BL, AL ; 累加到BL
INC SI ; SI指向下一个数据
LOOP L1 ; CX!=0继续循环
MOV RESULT, BL ; 保存结果
MOV AH, 4CH
INT 21H
CODES ENDS
END START
```
#### 程序分析
1. **数据段定义**
- `LIST DB 01H,02H,03H,04H,05H,06H,07H,08H,09H,0AH` 定义了一个数据表包含10个数据01H,02H,...,0AH即1,2,...,10
- `COUNT EQU 10` 定义了数据个数为10
- `RESULT DB ?` 用于存储累加结果
2. **循环结构**
- 使用SI作为指针变址寄存器通过 `LEA SI, LIST` 初始化为数据表首地址
- 使用CX作为循环计数器初值为10
- 使用BL寄存器存储累加和初值为0
3. **指令说明**
- `MOV AL, [SI]`从内存读取数据到AL
- `ADD BL, AL`将AL中的数据累加到BL
- `INC SI`SI指向下一个数据
- `LOOP L1`CX自动减1如果CX≠0则跳转到L1继续循环
4. **累加结果**
- 1+2+3+...+10 = 55 = 37H
- 结果存储在BL中即RESULT单元
#### 验证结果
运行程序后RESULT中保存累加和37H55
---
## 三、加强性实验
### 实验4_2 循环结构二:多重循环求累加和
#### 实验目的
掌握多重循环程序的设计方法,理解内嵌循环的汇编实现。
#### 实验内容
利用二重循环求累加和,体会外层循环和内层循环的配合。
#### 程序代码
```asm
DATAS SEGMENT
LIST DB 01H,02H,03H,04H,05H,06H,07H,08H,09H,0AH
COUNT EQU 10
RESULT DB ?
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
LEA SI, LIST ; SI指向数据表首地址
MOV CX, COUNT ; 外层循环计数
XOR BL, BL ; BL清0累加和初值为0
L1:
PUSH CX ; 保存外层循环计数
MOV CX, COUNT ; 内层循环计数
XOR BH, BH ; BH清0
L2:
MOV AL, [SI] ; 取出数据
ADD BH, AL ; 内层累加到BH
INC SI ; SI指向下一个数据
LOOP L2 ; 内层循环
POP CX ; 恢复外层循环计数
ADD BL, BH ; 外层累加
LOOP L1 ; 外层循环
MOV RESULT, BL ; 保存结果
MOV AH, 4CH
INT 21H
CODES ENDS
END START
```
#### 程序分析
1. **二重循环结构**
- **外层循环L1**:控制内层循环的执行次数
- **内层循环L2**:完成每次内层循环的累加操作
2. **寄存器保护**
- `PUSH CX`:在进入内层循环前保存外层循环计数器的值
- `POP CX`:在内层循环结束后恢复外层循环计数器的值
- 这是多重循环中保护外层计数器的重要技巧
3. **执行流程**
- 外层循环第1次内层循环累加10个数到BH然后BL+=BH
- 外层循环第2次内层循环再次累加10个数到BH然后BL+=BH
- 重复上述过程,直到外层循环结束
4. **累加原理**
- 内层循环将10个数据累加到BH
- 外层循环将每次内层循环的BH结果累加到BL
- 最终结果仍然是所有数据的总和55=37H
5. **注意问题**
- 8位寄存器BL、BH最大只能存储255累加和不应超过这个范围
- 本例中10个数的累加和为55小于255结果正确
#### 验证结果
运行程序后RESULT中保存最终的累加和37H55与实验4_1结果相同。
---
## 四、实验步骤
### 4.1 单重循环程序实验步骤
1. **编辑源程序**在编辑器中输入实验4_1的源代码保存为 `实验4_1_循环结构一.asm`
2. **汇编连接**
```
MASM 实验4_1_循环结构一.asm;
LINK 实验4_1_循环结构一.obj;
```
3. **运行程序**
```
实验4_1_循环结构一.exe
```
4. **调试观察**
- 在DEBUG中加载程序`DEBUG 实验4_1_循环结构一.exe`
- 使用 `T` 命令单步执行观察CX的变化
- 使用 `R` 命令查看寄存器状态
- 使用 `D` 命令查看RESULT单元的内容
### 4.2 多重循环程序实验步骤
1. **编辑源程序**在编辑器中输入实验4_2的源代码保存为 `实验4_2_循环结构二.asm`
2. **汇编连接**
```
MASM 实验4_2_循环结构二.asm;
LINK 实验4_2_循环结构二.obj;
```
3. **运行程序**
```
实验4_2_循环结构二.exe
```
4. **调试观察**
- 在DEBUG中观察PUSH/POP对栈的影响
- 跟踪内层循环L2和外层循环L1的执行
- 验证BH和BL的变化过程
---
## 五、思考题
### 5.1 LOOP指令的工作原理是什么
LOOP指令是8086汇编语言中实现循环的基本指令它完成以下操作
1. 将CX寄存器减1
2. 如果CX≠0则跳转到指定的标号处继续执行
3. 如果CX=0则继续执行下一条指令循环结束
LOOP指令相当于以下两条指令的组合
```
DEC CX
JNZ label
```
### 5.2 循环程序设计中需要注意哪些问题?
1. **循环计数器的初始化**在循环开始前必须给CX设置正确的初值
2. **循环条件的设置**:确保循环能够正确终止,避免死循环
3. **寄存器的保护**在多重循环中需要保护外层循环的计数器使用PUSH/POP指令
4. **数据指针的更新**如果使用指针访问数据必须正确更新指针如INC SI
5. **寄存器的选择**:根据数据范围选择合适的寄存器宽度,避免溢出
### 5.3 多重循环中为什么要保护外层循环计数器?
在多重循环中内层循环也会使用CX作为计数器。如果不保护外层循环的CX值当内层循环结束时CX会被内层循环修改为0导致外层循环无法正确继续。
通过PUSH指令在进入内层循环前保存CX的值内层循环结束后用POP指令恢复这样外层循环就能继续正确执行。
### 5.4 单重循环和多重循环有何区别?
1. **结构复杂度**
- 单重循环:只有一层循环结构
- 多重循环:有多层循环嵌套,外层循环包含内层循环
2. **计数器使用**
- 单重循环CX在整个循环过程中只需要一个值
- 多重循环需要保护外层循环计数器内层循环可以复用CX
3. **应用场景**
- 单重循环:处理简单的重复操作,如累加一个数组
- 多重循环:处理矩阵运算、多维数组遍历等复杂问题
---
## 六、实验总结
1. **循环程序的基本结构**:初始化循环计数器 → 循环体 → 更新循环条件 → LOOP指令跳转
2. **LOOP指令的理解**LOOP指令自动完成CX减1和条件判断跳转是实现循环的关键指令
3. **单重循环的应用**:适用于处理线性结构的数据,如数组求和、数据查找等
4. **多重循环的设计要点**
- 外层循环控制执行次数
- 内层循环完成具体操作
- 使用PUSH/POP保护外层计数器
- 注意内外层循环的配合
5. **循环程序调试技巧**
- 观察CX的变化确认循环次数正确
- 检查指针更新,确保数据访问正确
- 注意寄存器的值,避免溢出
6. **循环程序设计的优势**:使用循环结构可以大大减少重复代码,提高程序的可读性和效率