477 lines
8.6 KiB
Markdown
477 lines
8.6 KiB
Markdown
# 实验三:分支程序设计
|
||
|
||
## 一、实验目的
|
||
|
||
1. 掌握汇编语言分支程序设计的基本方法
|
||
2. 熟悉条件转移指令和和无条件转移指令的使用
|
||
3. 理解程序流程图的设计方法
|
||
|
||
## 二、实验内容
|
||
|
||
### 2.1 基础性实验
|
||
|
||
#### 实验1:符号数比较
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-1:符号数比较
|
||
; 功能:比较X和Y两个符号数的大小
|
||
; 说明:如果X >= Y,则Z = Y;否则Z = X
|
||
|
||
DATA SEGMENT
|
||
X DW 1234H
|
||
Y DW 5678H
|
||
Z DW ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
MOV AX, X
|
||
CMP AX, Y
|
||
JGE NEXT
|
||
MOV Z, AX
|
||
JMP EXIT
|
||
NEXT:
|
||
MOV Z, Y
|
||
EXIT:
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 比较X和Y两个符号数的大小
|
||
- 如果X >= Y,则Z = Y;否则Z = X
|
||
- 使用CMP指令比较,使用JGE条件转移
|
||
|
||
**【运行结果】**
|
||
|
||
因为5678H > 1234H,所以Z单元存放5678H
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果X = -1(假设为16位有符号数FFFFH),Y = 1,程序输出什么?
|
||
2. JGE指令和JA指令有什么区别?
|
||
|
||
---
|
||
|
||
#### 实验2:分支程序示例1 - 求两个数中的较大值
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-2:分支程序示例1 - 求两个数中的较大值
|
||
; 功能:求X和Y中的较大值,存入Z
|
||
|
||
DATA SEGMENT
|
||
X DB 10
|
||
Y DB 20
|
||
Z DB ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
MOV AL, X
|
||
CMP AL, Y
|
||
JA NEXT
|
||
MOV AL, Y
|
||
NEXT:
|
||
MOV Z, AL
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 求X和Y中的较大值,存入Z
|
||
- 使用JA(高于则跳转)指令,用于无符号数比较
|
||
- 这是一个典型的双分支结构
|
||
|
||
**【运行结果】**
|
||
|
||
Z = 20(Y的值,因为20 > 10)
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果X = Y,程序输出什么?
|
||
2. 如果要修改为求较小值,如何改动?
|
||
|
||
---
|
||
|
||
#### 实验3:分支程序示例2 - 求两个数的差的绝对值
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-3:分支程序示例2 - 求两个数的差的绝对值
|
||
; 功能:求X和Y的差的绝对值,存入Z
|
||
|
||
DATA SEGMENT
|
||
X DB 5
|
||
Y DB 3
|
||
Z DB ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
MOV AL, X
|
||
CMP AL, Y
|
||
JZ EQUAL ;如果X=Y则跳转到EQUAL
|
||
JNS PLUS ;如果X>Y则跳转到PLUS(正数)
|
||
MOV BL, Y
|
||
SUB BL, AL
|
||
MOV Z, BL
|
||
JMP EXIT
|
||
PLUS:
|
||
MOV BL, AL
|
||
SUB BL, Y
|
||
MOV Z, BL
|
||
JMP EXIT
|
||
EQUAL:
|
||
MOV Z, 0
|
||
EXIT:
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 求X和Y的差的绝对值,存入Z
|
||
- 使用多条件分支:
|
||
- X = Y时,Z = 0
|
||
- X > Y时,Z = X - Y
|
||
- X < Y时,Z = Y - X
|
||
|
||
**【运行结果】**
|
||
|
||
Z = 2(5 - 3 = 2)
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果X = 3,Y = 5,程序输出什么?
|
||
2. JNS指令的含义是什么?什么时候会跳转?
|
||
|
||
---
|
||
|
||
### 2.2 加强性实验
|
||
|
||
#### 实验4:成绩分类程序
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-4:成绩分类程序
|
||
; 功能:根据分数分类为A/B/C/D/E
|
||
; 90分以上为A,80-89为B,70-79为C,60-69为D,60分以下为E
|
||
|
||
DATA SEGMENT
|
||
SCORE DB 85
|
||
GRADE DB ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
MOV AL, SCORE
|
||
CMP AL, 90
|
||
JAE A_GRADE
|
||
CMP AL, 80
|
||
JAE B_GRADE
|
||
CMP AL, 70
|
||
JAE C_GRADE
|
||
CMP AL, 60
|
||
JAE D_GRADE
|
||
MOV GRADE, 'E'
|
||
JMP EXIT
|
||
A_GRADE:
|
||
MOV GRADE, 'A'
|
||
JMP EXIT
|
||
B_GRADE:
|
||
MOV GRADE, 'B'
|
||
JMP EXIT
|
||
C_GRADE:
|
||
MOV GRADE, 'C'
|
||
JMP EXIT
|
||
D_GRADE:
|
||
MOV GRADE, 'D'
|
||
EXIT:
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 根据分数进行成绩分类
|
||
- 90分以上为A,80-89为B,70-79为C,60-69为D,60分以下为E
|
||
- 使用多个CMP和JAE指令实现多分支
|
||
|
||
**【运行结果】**
|
||
|
||
GRADE = 'B'(85分属于B级)
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果分数是100分,程序输出什么等级?
|
||
2. 如何修改程序实现60分以下的提示"不及格"?
|
||
|
||
---
|
||
|
||
#### 实验5:字符分类程序
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-5:字符分类程序
|
||
; 功能:判断大写/小写字母或其他字符
|
||
; 结果:1=大写字母,2=小写字母,3=其他字符
|
||
|
||
DATA SEGMENT
|
||
CH DB 'A'
|
||
RESULT DB ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
MOV AL, CH
|
||
CMP AL, 'A'
|
||
JNB NL_CHECK
|
||
JMP OTHER
|
||
NL_CHECK:
|
||
CMP AL, 'Z'
|
||
JNA UPLETTER
|
||
CMP AL, 'a'
|
||
JNB LL_CHECK
|
||
JMP OTHER
|
||
LL_CHECK:
|
||
CMP AL, 'z'
|
||
JNA LOWLETTER
|
||
JMP OTHER
|
||
UPLETTER:
|
||
MOV RESULT, 1 ;大写字母
|
||
JMP EXIT
|
||
LOWLETTER:
|
||
MOV RESULT, 2 ;小写字母
|
||
JMP EXIT
|
||
OTHER:
|
||
MOV RESULT, 3 ;其他字符
|
||
EXIT:
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 判断字符CH的类型
|
||
- 1 = 大写字母,2 = 小写字母,3 = 其他字符
|
||
- 使用JNB/JNA/JNN等指令进行字符比较
|
||
|
||
**【运行结果】**
|
||
|
||
RESULT = 1(A是大写字母)
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果CH = 'm',程序输出什么结果?
|
||
2. 如果CH = '5'(数字),程序输出什么结果?
|
||
|
||
---
|
||
|
||
#### 实验6:求最大值程序
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-6:求最大值程序
|
||
; 功能:从10个数中找最大值
|
||
|
||
DATA SEGMENT
|
||
ORG 1000H
|
||
ARR DB 10, 25, 3, 47, 15, 38, 92, 6, 71, 20
|
||
MAX DB ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
LEA SI, ARR
|
||
MOV CX, 9
|
||
MOV AL, [SI]
|
||
INC SI
|
||
NEXT:
|
||
CMP AL, [SI]
|
||
JGE SKIP
|
||
MOV AL, [SI]
|
||
SKIP:
|
||
INC SI
|
||
LOOP NEXT
|
||
MOV MAX, AL
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 从10个无符号数中找出最大值
|
||
- 使用循环和比较指令
|
||
- 每次比较后如果发现更大的值则更新AL
|
||
|
||
**【运行结果】**
|
||
|
||
MAX = 92(数组中的最大值)
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果要求最小值,程序如何修改?
|
||
2. 循环次数为什么是9而不是10?
|
||
|
||
---
|
||
|
||
#### 实验7:符号函数程序
|
||
|
||
**【程序清单】**
|
||
|
||
```assembly
|
||
; 实验三-7:符号函数程序
|
||
; 功能:计算符号函数Y
|
||
; Y = 1 (X>0), Y = 0 (X=0), Y = -1 (X<0)
|
||
|
||
DATA SEGMENT
|
||
X DW 5
|
||
Y DW ?
|
||
DATA ENDS
|
||
|
||
CODE SEGMENT
|
||
ASSUME CS:CODE, DS:DATA
|
||
START:
|
||
MOV AX, DATA
|
||
MOV DS, AX
|
||
MOV AX, X
|
||
CMP AX, 0
|
||
JG POSITIVE
|
||
JL NEGATIVE
|
||
MOV Y, 0
|
||
JMP EXIT
|
||
POSITIVE:
|
||
MOV Y, 1
|
||
JMP EXIT
|
||
NEGATIVE:
|
||
MOV Y, -1
|
||
EXIT:
|
||
MOV AH, 4CH
|
||
INT 21H
|
||
CODE ENDS
|
||
END START
|
||
```
|
||
|
||
**【程序说明】**
|
||
|
||
- 计算符号函数:Y = 1 (X>0), Y = 0 (X=0), Y = -1 (X<0)
|
||
- 使用CMP指令和JG/JL条件转移
|
||
|
||
**【运行结果】**
|
||
|
||
Y = 1(因为5 > 0)
|
||
|
||
**【思考题】**
|
||
|
||
1. 如果X = -10,程序的输出结果是什么?
|
||
2. 如果X = 0,程序的输出结果是什么?
|
||
|
||
---
|
||
|
||
## 三、实验步骤
|
||
|
||
1. 分析题目要求,设计程序流程图
|
||
2. 根据流程图编写汇编源程序
|
||
3. 编辑源程序,保存为.ASM文件
|
||
4. 使用MASM汇编程序进行汇编
|
||
5. 使用LINK链接程序进行链接
|
||
6. 运行程序并观察结果
|
||
7. 使用DEBUG调试程序,验证结果
|
||
|
||
## 四、实验结果分析
|
||
|
||
### 分支程序设计要点总结
|
||
|
||
1. **条件转移指令的选择**
|
||
- 无符号数比较:用JA/JAE/JB/JBE等
|
||
- 有符号数比较:用JG/JGE/JL/JLE等
|
||
- 特定条件:JE/JNE/JZ/JNZ等
|
||
|
||
2. **分支结构的设计方法**
|
||
- 双分支:使用CMP + 条件跳转 + 无条件跳转
|
||
- 多分支:逐个比较,逐层筛选
|
||
|
||
3. **流程图的重要性**
|
||
- 清晰表达程序执行流程
|
||
- 便于发现逻辑错误
|
||
- 有助于程序调试
|
||
|
||
## 五、思考题参考答案
|
||
|
||
### 实验1
|
||
1. 如果X = FFFFH(-1),Y = 1,程序输出Z = 1(因为JGE时-1 < 1)
|
||
2. JGE用于有符号数比较(>=),JA用于无符号数比较(>)
|
||
|
||
### 实验2
|
||
1. 如果X = Y,AL保持Y的值,Z = Y
|
||
2. 将JA改为JB即可求较小值
|
||
|
||
### 实验3
|
||
1. 如果X = 3,Y = 5,输出Z = 2
|
||
2. JNS:符号位为0(即正数)时跳转
|
||
|
||
### 实验4
|
||
1. 100分输出'A'
|
||
2. 将GRADE = 'E'改为显示"不及格"字符串
|
||
|
||
### 实验5
|
||
1. 'm'输出2(小写字母)
|
||
2. '5'输出3(其他字符)
|
||
|
||
### 实验6
|
||
1. 将JGE改为JLE即可找最小值
|
||
2. 循环9次因为第1个数已经作为初始最大值
|
||
|
||
### 实验7
|
||
1. X = -10时,输出Y = -1
|
||
2. X = 0时,输出Y = 0
|
||
|
||
## 六、实验总结
|
||
|
||
通过本次实验,我掌握了汇编语言分支程序设计的基本方法:
|
||
|
||
1. 学会了使用CMP指令进行数值比较
|
||
2. 熟悉了各种条件转移指令(JE/JNE/JG/JL/JA/JB等)
|
||
3. 理解了单分支、双分支和多分支程序的设计
|
||
4. 掌握了循环+分支结合的复杂程序设计
|
||
5. 学会了使用流程图规划程序结构 |