danger 本博客仅为博主记录课程报告使用,所学尚浅如有错误,请指出^__^

记录大二上学期《微机原理及应用》课程最后的大作业:使用汇编语言进行程序编写,同时使用Dosbox软件进行仿真观察寄存器的变化。

实验一、汇编程序编写基础

1.1 实验内容及要求

1.1.1 实验内容

编写一个汇编程序,从xx单元开始的30个连续单元中存放有30个无符号数,从中找出最大者送入yy单元。

1.1.2 实验要求

(1)给出汇编语言源程序

(2)截图记录编译和调试过程

(3)使用DEBUG调试命令查看指令执行后寄存器内容的变化并截图

(4)规范撰写实验报告

1.2 实验步骤及结果

1.2.1 实验步骤

(1)任务分析:根据题意,我们把第一个数先送入AL寄存器,将AL中的数与后面的29个数逐个进行比较。如果AL中的数较小,则两数交换位置;如果AL中的数大于等于相比较的数,则两数不交换位置。在比较过程中,AL中始终保持较大的数,比较29次,则最大者必在AL中。最后把AL中的数(最大者)送入yy单元。

(2)编写汇编源程序。

(3)对源程序进行编译、连接,生成.exe文件。

(4)启动调试程序,查看寄存器中的内容是否正确。

1.2.2 程序编写

实验完成顺序程序设计的源程序编写如下

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
;编写一个源程序,从XX单元开始的30个连续单元中放有30个无符号数
;找出最大这送入YY单元

DATA SEGMENT ;数据段开始
XX DB 176, 188, 22, 181, 37, 110, 63, 189, 127, 163
DB 114, 16, 59, 70, 27, 27, 190, 104, 46, 106
DB 75, 111, 188, 63, 92, 66, 50, 59, 65, 14 ;定义字节变量XX数组存放30个数
LEN = ($ - XX) / TYPE XX ;计算XX的长度
YY DB ? ;定义字节变量YY,存放结果
DATA ENDS ;数据段结束
CODE SEGMENT ;程序段开始
ASSUME CS:CODE, DS:DATA
BEGIN: MOV AX, DATA ;程序开始,通过AX将数据段基址送入DS
MOV DS, AX
LEA SI, XX ;获取XX数据区的偏移地址送入指针SI
MOV AL, [SI] ;通过指针将XX数组中的数送入AL中,指定第一个数为最大
MOV CX, LEN-1 ;设置循环次数30-1=29
NEXT: INC SI ;指针加一,指向下一个数
CMP AL, [SI] ;比较当前AL(当前最大)中的数和SI指向的数
JAE L1 ;AL中的数大于或等于SI指向的数,则跳转到L1继续循环
XCHG AL, [SI] ;交换AL与SI指向的数
L1: LOOP NEXT ;跳转到循环体NEXT
MOV YY, AL ;将AL中的中放入最大数送入到YY中,完成!nice!
STOP: MOV AH, 4CH
INT 21H ;返回DOS
CODE ENDS ;程序段结束
END BEGIN ;程序结束

1.3 单步执行及分析结果

1.3.1 编译

编译

1.3.2 链接

链接

1.3.3 执行

1.3.4 输出

1.3.5 执行过程分析

过程一

过程二

过程三

过程四

实验二、顺序程序设计

2.1 实验内容及要求

2.1.1 实验内容

编写程序将双字变量VAR1 与VAR2 相加,结果保存在 VAR1 中。用 DEBUG 跟踪分析程序运行的结果。

2.1.2 实验要求

(1)给出汇编语言源程序

(2)截图记录编译和调试过程

(3)使用DEBUG调试命令查看指令执行后寄存器内容的变化并截图

(4)撰写规范的实验报告

2.2 实验步骤及结果

2.2.1 实验步骤

(1)任务分析:在数据段中定义变量VAR1VAR2,编写程序将两个变量相加,结果保存在VAR1中。双字变量相加时必须分成两部分分,高16 位相加时,要用带进位的加法,把D15 位(最低位为D0 位)相加产生的进位加上。注意:由于这两个变量是双字类型的,在访问时需要使用 PTR 伪指令。(注意:VAR1的值对应本人学号的后八位,VAR2的值对应本人学号的后八位的倒序排列

(2)编写汇编源程序

(3)对源程序进行编译、连接,生成.exe文件

(4)启动调试程序,查看寄存器中的内容是否正确

2.2.2 程序编写

实验二完成顺序程序设计的源程序编写如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
;本人学号 211040200102 
;学号后八位(stuvwxyz):40200102
;学号后八位倒顺序(stuvwxys):20100204
;实验目的:stuvwxyz与stuvwxys相加结果保存在VAR1中
DATA SEGMENT
VAR1 DD 40200102H ;数1 VAR1, 40200102
VAR2 DD 20100204H ;数2 VAR2, 20100204
DATA ENDS ;数据段结束
CODE SEGMENT
ASSUME CS:CODE, DS:DATA

BEGIN: MOV AX,DATA ;把数据段的段地址送入AX
MOV DS,AX ;把数据段段地址通过AX送入DS
MOV AX,WORD PTR VAR1 ;取变量VAR1的低地址部分0102H
ADD AX, WORD PTR VAR2 ;AX中的0102H与VAR2的低地址部分相加,并将结果存入AX
MOV WORD PTR VAR1, AX ; 将AX中的结果存入VAR1的低地址部分
MOV AX, WORD PTR VAR1+2 ;将 VAR1的高地址部分4020H送入AX
ADC AX, WORD PTR VAR2+2 ; AX中的4020H与VAR2的高地址相加(带进位),并将结果存入AX
MOV WORD PTR VAR1+2, AX ;将AX中的结果存入VAR1的高地址部分
STOP: MOV AX, 4C00H ;返回DOS, 不需要执行
INT 21H
CODE ENDS
END BEGIN

2.3 单步执行及分析结果如下

2.3.1 编译

编译

2.3.2 链接

链接

2.3.3 执行

2.3.4 输出

2.3.5 执行过程分析

实验三、分支程序设计

3.1 实验内容及要求

3.1.1 实验内容

计算分段函数$Y=\begin{cases}3x && x<20 \ x-20 && x\geq20 \end{cases}$,其中X和Y是无符号字节数。

3.1.2 实验要求

(1)给出汇编语言源程序

(2)截图记录编译和调试过程

(3)使用DEBUG调试命令查看指令执行后寄存器内容的变化并截图

(4)撰写规范的实验报告

3.2 实验步骤及结果

3.2.1 实验步骤

(1)任务分析:首先需要在数据段中定义变量X和Y。由于X和Y是无符号字节数,因此应使用无符号数的条件转移指令进行分支跳转

(2)编写汇编源程序

(3)对源程序进行编译、连接,生成.exe文件

(4)启动调试程序,查看寄存器中的内容是否正确

3.2.2 程序编写

实验三完成分支程序设计的源程序编写如下(初始X值设置为2)

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
;编写程序计算分段函数
;当X<20时Y=3X;当X>=20时,Y=X-20
;其中X和Y均为无符号数
;要求x的初值是1m,1m是学号最后一位数字(即2, 我的学号为211040200102)
DATA SEGMENT
X DB 2 ;定义变量X,字节类型里面存放2(学号的最后一位)
Y DB ? ;定义变量Y,字节类型用来存放最终结果
DATA ENDS ;数据段结束
CODE SEGMENT
ASSUME CS:CODE, DS:DATA

BEGIN: MOV AX, DATA ;把数据段基址送入AX
MOV DS, AX ;把AX中的基址送入DS
MOV AL, X ;将X的值送入AL中
CMP AL, 20 ;AL中的值(2)与20作比较(在程序执行时将2和20均换算成十六进制即:2H与14H作比较)
JAE ABOVE ;若条件成立则跳转到ABOVE(无符号)
MOV BL, 3 ;若条件不成立则执行下列程序,将3存入BL
MUL BL ;将AL与BL相乘(无符号)
JMP RESULT ;跳转到RESULT(在条件不成立分支上执行)
ABOVE: SUB AL, 20 ;条件成立,执行AL的内容-20
RESULT: MOV Y, AL ;将AL的内容送入Y中
STOP: MOV AX, 4C00H ;begin程序结束
INT 21H
CODE ENDS ;程序段结束
END BEGIN ;程序结束

3.3 单步执行及结果分析

3.3.1 编译

3.3.2 链接

3.3.3 执行

3.3.4 输出

当$X=2$时, 由$Y=3*X$得:$Y=6$

当$X=28$时,由$Y=X-20$得:$Y=08$

3.3.5 执行过程分析

①X小于20时执行$Y=3X$

②X大于等于20时执行$Y=X-20$(这里直接使用e命令对X进行修改为$X=28$,预计输出$Y=28-20=8$)

实验四、循环程序设计

4.1 实验内容及要求

4.1.1 实验内容

从 BUFFER 开始的内存单元中,顺序存放着12个无符号字节数据(为自己的学号),编写程序从中查找最大和最小的数,置于 MAX 和 MIN 单元中。在屏幕上显示自己的姓名拼音和学号,并把学号中的最大和最小数输出到屏幕上。

4.1.2 实验要求

(1)给出汇编语言源程序

(2)截图记录编译和调试过程

(3)使用DEBUG调试命令查看指令执行后寄存器内容的变化并截图

(4)撰写规范的实验报告

4.2 实验步骤及结果

4.2.1 实验步骤

(1)任务分析:首先需要在数据段中定义变量BUFFER、MAX和MIN。查找最大和最小数的方法是:假定第一个数是当前最大/最小的数,然后从第二个数开始,依次取出与当前最大/最小数进行比较,若数值大于/小于当前最大/最小数,则用该数值替换当前最大/最小数。经过 N−1 次比较后,程序结束。注意:由于要查找的数是有符号数,因此应使用有符号数的条件转移指令。最后利用合适的DOS功能调用,显示字符串和单个字符

(2)编写汇编源程序

(3)对源程序进行编译、连接,生成.exe文件

(4)启动调试程序,查看寄存器中的内容是否正确

4.2.2 程序编写

实验四完成循环程序设计的源程序编写

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
;编写循环程序
;要求找出数组BUFFER中最大和最小的数置于MAX,MIN单元
;数据区顺序存放12个有符号数(为自己的学号,即2,1,1,0,4,0,2,0,0,1,0,2)
;程序最后在屏幕上显示自己的名字拼英和学号(chenchuang)
;把学号中的最大和最小数输出到屏幕上
DATA SEGMENT ;数据段开始
VAR1 DB 'CHENCHUANG', '$' ;定义变量VAR1存放字符串我的姓名拼音(CHENCHUANG)
VAR2 DB '211040200102', '$' ;定义变量VAR2存放字符串我的学号(211040200102)
CR DB 0DH, 0AH,'$' ;定义变量存放回车换行的ASCII码
VAR3 DB 'The max num is:', '$'
VAR4 DB 'The min num is:', '$'
BUFFER DB 2, 1, 1, 0, 4, 0, 2, 0, 0, 1, 0, 2 ;定义数组BUFFER存放学号的个个位对应的数
LEN = ($ - BUFFER) / TYPE BUFFER ;计算数组BUFFER的长度(存放的数字个数,即12)
MAX DB ? ;用来存放最大的数
MIN DB ? ;用来存放最小的数
DATA ENDS ;数据段结束
CODE SEGMENT ;程序段开始
ASSUME CS:CODE, DS:DATA
BEGIN: MOV AX, DATA ;将数据段基址通过AX送入DS
MOV DS, AX
LEA SI, BUFFER ;将BUFFER的段基址送入SI(指针)(即第一个数的偏移地址)
MOV AL, [SI] ;将[SI]指向的内存单元的内容送入AL
MOV MAX, AL ;假设第一个数是最大的
MOV MIN, AL ;假设第一个数是最大的
MOV CX, LEN-1 ;设置循环次数,即CX=12-1
NEXT: INC SI ;循环体,SI+1(指针加一)指向下一个数
MOV AL, [SI] ;将[SI]指向的内存单元的内容送入AL
CMP AL, MAX ;比较AL中的数与当前最大的数MAX
JL L1 ;当前AL中的数比当前最大的数MAX小,则跳转到L1
G1: MOV MAX, AL ;当前AL中的数比MAX大则将AL中的数存入MAX
L1: CMP AL, MIN ;比较AL中的数与当前最小的数MIN
JG LP ;当前AL中的数既不比当前MAX大也不比当前MIN小,跳转到LP,继续循环
MOV MIN, AL ;当前AL中的数比MIN小则将AL中的数存入MIN
LP: LOOP NEXT ;执行循环体
;屏幕输出名字
MOV DX, OFFSET VAR1 ;OFFSET获取变量的偏移地址送入DX
MOV AH, 9 ;调用9号系统功能,屏幕上输出字符串“$”
INT 21H ;返回DOS
;换行
MOV DX, OFFSET CR ;CR中存放的是回车换行的ASCII码
MOV AH, 9 ;输出换行
INT 21H ;返回DOS
;屏幕输出学号
MOV DX, OFFSET VAR2
MOV AH, 9
INT 21H
;换行
MOV DX, OFFSET CR
MOV AH, 9
INT 21H
;屏幕输出最大值
MOV DX, OFFSET VAR3
MOV AH, 9
INT 21H
MOV DL, MAX
ADD DL, 30H ;加30H计算处MAX的ASCII码
MOV AH, 2 ;2号系统功能调用根据DL中的ASCII输出
INT 21H
;换行
MOV DX, OFFSET CR
MOV AH, 9
INT 21H
;屏幕输出最小值
MOV DX, OFFSET VAR4
MOV AH, 9
INT 21H
MOV DL, MIN
ADD DL, 30H
MOV AH, 2
INT 21H
STOP: MOV AH, 4CH
INT 21H
CODE ENDS ;程序段结束
END BEGIN ;程序结束

4.3 单步执行及结果分析

4.3.1 编译

4.3.2 链接

4.3.3 运行

4.3.4 输出

4.3.5 执行过程分析