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