汇编语言程序设计 实验报告-1

1. 实验目的

  1. 掌握顺序程序设计方法
  2. 掌握分支程序的结构及分支程序的设计、调试方法
  3. 学习数据传送及算术和逻辑运算指令的用法
  4. 熟悉在 PC 机上建立、汇编、连接、调试和运行汇编语言程序的过程

2. 实验内容

2.1 任务一

有一字变量 BUF1 是以原码表示的有符号数,要求将其转换为反码和补码,分别存入 BUF2 和 BUF3 单元,并在屏幕上显示出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
DATA SEGMENT
BUF1 DW 9348H
BUF2 DW 4 DUP(0),0AH,0DH,'$'
BUF3 DW 4 DUP(0),'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN:
MOV AX,DATA
MOV DS,AX
MOV AX,BUF1
ADD AX,0
JS NEXT
MOV BUF2,AX
MOV BUF3,AX
JMP EEE
NEXT:
AND AX,7FFFH
NOT AX
MOV BUF2,AX
INC AX
MOV BUF3,AX
EEE:
MOV CX,0004H
MOV DI,OFFSET BUF2
MOV DX,[DI]
ADD DI,03
BBB:
MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB QQQ
ADD AL,07H
QQQ:
ADD AL,30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL,04H
SHR DX,CL
POP CX
LOOP BBB
MOV CX,0004H
MOV SI, OFFSET BUF3
MOV DX,[SI]
ADD SI,03H
CCC:
MOV AX,DX
AND AX,000FH
CMP AL,0AH
JB DDD
ADD AL,07H
DDD:
ADD AL,30H
MOV [SI],AL
DEC SI
PUSH CX
MOV CL,04H
SHR DX, CL
POP CX
LOOP CCC
MOV DX,OFFSET BUF2
MOV AH,09H
INT 21H
MOV DX,OFFSET BUF3
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN

2.2 任务二

有两个两字节无符号数分别放在存储单元 A、B 起始的缓冲器中,求其和。结果放在 A 起始的缓冲区并在屏幕上显示。相加若有进位不存入存储单元。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
DATA SEGMENT
A DB 34H,18H,2 DUP(0),'$'
B DB 56H,83H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV AL,A
MOV BL,B
ADD AL,BL
MOV AH,A+1
MOV BH, B+1
ADC AH, BH
MOV A, AL
MOV A+1, AH
MOV CX, 0004H
MOV DI, OFFSET A
MOV DX, [ DI]
ADD DI,03
NEXT:
MOV AX, DX
AND AX,000FH
CMP AL,0AH
JB QQQ
ADD AL, 07H
QQQ:
ADD AL, 30H
MOV [DI], AL
DEC DI
PUSH CX
MOV CL, 04
SHR DX, CL
POP CX
LOOP NEXT
MOV DX, OFFSET A
MOV AH, 09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START

2.3 任务三

在 BUF 和 BUF+1、BUF+2 单元分别放有一个无符号字节型数,编程序将其中最大数存入 MAX 单元,并在屏幕上显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
STACK SEGMENT  STACK
DB 1024 DUP(0)
STACK ENDS
DATA SEGMENT
BUF DB 70H,35H,1FH
MAX DB 2 DUP(?),'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN:
MOV AX, DATA
MOV DS, AX
MOV AL, BUF
CMP AL, BUF+1
JNB LP1
MOV AL, BUF+1
LP1:
CMP AL, BUF+2
JAE LP2
MOV AL, BUF+2
LP2:
MOV CX, 02H
MOV DI, OFFSET MAX
MOV DL, AL
INC DI
LP3:
AND AL, 0FH
CMP AL, 0AH
JB LP4
ADD AL, 07H
LP4:
ADD AL, 30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL, 04
SHR DL, CL
POP CX
MOV AL, DL
LOOP LP3
MOV DX, OFFSET MAX
MOV AH, 09H
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN

2.4 任务四

在 BUF 和 BUF+1、BUF+2 单元分别放有一个有符号字节型数,编程序将其中最大数存入 MAX 单元,并在屏幕上显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
STACK SEGMENT  STACK
DB 1024 DUP(0)
STACK ENDS
DATA SEGMENT
BUF DB 98H,75H,32H
MAX DB 2 DUP(?),'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN:
MOV AX, DATA
MOV DS, AX
MOV AL, BUF
CMP AL, BUF+1
JG LP1
XCHG AL, BUF+1
LP1:
CMP AL, BUF+2
JG LP2
XCHG AL, BUF+2
LP2:
MOV MAX, AL
MOV CX, 02H
MOV DI, OFFSET MAX
MOV DL, [DI]
INC DI
LP3:
MOV AL, DL
AND AL, 0FH
CMP AL, 0AH
JB LP4
ADD AL, 07H
LP4:
ADD AL, 30H
MOV [DI],AL
DEC DI
PUSH CX
MOV CL, 04
SHR DX, CL
POP CX
LOOP LP3
MOV DX, OFFSET MAX
MOV AH, 09H
INT 21H
MOV AH, 4CH
INT 21H
CODE ENDS
END BEGIN

2.5 任务五

将 1000H 单元开始的 10 个字节数,采用奇偶校验,将奇数在前偶数在后仍存回原数据区。本实验要求在 DEBUG 调试状态下进行,包括汇编程序、运行程序、检查结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ORG     2000H
2000 BE0010 MOV SI, 1000
2003 BF0910 MOV DI, 1009
2006 8A14 MOV DL, [SI]
2008 80C200 ADD DL, 00
200B 7B0B JPO 2018
200D 8615 XCHG DL, [DI]
200F 8814 MOV [SI], DL
2011 4F DEC DI
2012 39FE CMP SI, DI
2014 7407 JE 201D
2016 EBF0 JMP 2008
2018 46 INC SI
2019 8A14 MOV DL, [SI]
201B EBF5 JMP 2012
201D F4 HLT

2.6 任务六

从键盘上接收一位十进制数 X,计算 Y 值,并以十六进制形式显示出来,Y 按下列公式计算。

$$
Y = \begin{cases}
X^2 + X & (X=3) \
X^2 - 2X & (X=4) \
X^2 & (X=5) \
\frac{X^2}{2} & (X=6)
\end{cases}
$$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
DATA SEGMENT
TABLE DW L1,L2,L3,L4,L5,L6
MSG1 DB 'Please input an integer :$'
MSG2 DB 'Y=$'
MSG3 DB 'Illegally input!$'
DATA ENDS
STACK1 SEGMENT PARA STACK
DW 20H DUP(0)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START:
MOV AX,DATA
MOV DS,AX

LEA DX,MSG1
MOV AH,09H
INT 21H ;输出提示信息

MOV AH,01H
INT 21H ;输入一个数字

CMP AL,33H
JB GEND
CMP AL,36H
JA GEND
AND AL,0FH ;转换为数字
XOR AH,AH ;高位清零
DEC AL ;获取 x-1
SHL AL,1 ;计算 L
MOV BX,OFFSET TABLE ;获取 table 的内容
ADD BX,AX
JMP [BX]

GEND:
MOV DL,0AH
MOV AH,02H
INT 21H ;换行
LEA DX,MSG3
MOV AH,09H
INT 21H ;显示提示错误信息
JMP L7

L1:
JMP GEND

L2:
JMP GEND

L3:
CALL HHSC
MOV DL,31H
MOV AH,02H
INT 21H
MOV DL,32H
MOV AH,02H
INT 21H
JMP L7

L4:
CALL HHSC
MOV DL,38H
MOV AH,02H
INT 21H
JMP L7

L5:
CALL HHSC
MOV DL,32H
MOV AH,02H
INT 21H
MOV DL,35H
MOV AH,02H
INT 21H
JMP L7

L6:
CALL HHSC
MOV DL,31H
MOV AH,02H
INT 21H
MOV DL,38H
MOV AH,02H
INT 21H
JMP L7

L7:
MOV AH,4CH
INT 21H ;终止程序

HHSC PROC
MOV DL,0AH
MOV AH,02H
INT 21H ;换行
LEA DX,MSG2
MOV AH,09H
INT 21H ;显示输出信息
RET
HHSC ENDP

CODE ENDS
END START

2.7 任务七

从键盘上接收两个一位十六进制数 X 和 Y,然后再输入一个 A-D 之间的一个字符,按下列要求计算。

  • 当输入字符为 A,则计算 X+Y,并以十六进制形式显示出来
  • 当输入字符为 B,则计算 X-Y,并以十六进制形式显示出来
  • 当输入字符为 C,则计算 X*Y,并以十六进制形式显示出来
  • 当输入字符为 D,则计算 X/Y,并以十六进制形式显示出来
1
;欸嘿, 没写捏, 自己试试吧?

3. 调试步骤

  1. 分析题目,将程序中的原始数据和最终结果的存取方法确定好
  2. 画出流程图
  3. 写出源程序
  4. 对程序中的结果进行分析,并准备好上机调试与用汇编程序及汇编调试的过程

4. 分析与思考

  1. 常用指令
指令 指令功能
mov reg, data reg = data
add reg, data reg = reg + data
sub reg, data reg = reg - data
mul reg ax = ax * reg
div reg 当 reg 为 8 位, ah = ax / reg, al = ax % reg. 当 reg 为 16 位, ax = ax / reg, dx = ax % reg.
cmp a, b a == b zf = 1
a != b zf = 0
a < b cf = 1
a >= b cf = 0
a > b cf = 0, zf = 0
a <= b cf = 1, zf = 1
jb tag 当 cf = 1, 跳转到 tag
je tag 当 zf = 1, 跳转到 tag
jmp tag 无条件跳转到 tag
  1. 标志位寄存器
寄存器 功能
sf 符号标志位, 运算结果为负时为 1
cf 进位标志位(无符号数)当向最高位进位或借位时为 1
of 溢出标志位(有符号数)当有符号数运算发生溢出时为 1
  1. 汇编分支程序的实现

程序设计过程中,需要根据给定条件选择执行的代码片段时,需要程序实现跳转程序指针到指定代码片段的功能,8086 提供的多个跳转语句可配合程序标号一同使用。

编译时,编译器将自动把程序标号替换为对应指令的地址。因此,通过合理的设计标号,配合运算指令对寄存器的更改效果,可利用不同的跳转指令实现程序的分支选择。

附录

  1. 文件列表

    • 8086-8088 汇编语言指令表.pdf
  2. 下载地址


汇编语言程序设计 实验报告-1
https://flowerdown.org/posts/20221217-141104
作者
Unrealfeathers
发布于
2022年12月17日
许可协议