北京邮电大学微机原理软件实验报告.docx
《北京邮电大学微机原理软件实验报告.docx》由会员分享,可在线阅读,更多相关《北京邮电大学微机原理软件实验报告.docx(50页珍藏版)》请在冰点文库上搜索。
北京邮电大学微机原理软件实验报告
微机原理软件实验报告
学院:
信息与通信工程学院
班级:
XXXXXX
姓名:
XXXXX
学号:
XXXXXXXX
班内序号:
XXXXX
日期:
2017年11月30日
实验一DEBUG的使用
一、实验目的:
1.掌握汇编程序的编辑,编译,连接和执行的全过程;
2.学习和掌握用DEBUG调试程序的方法.
二、实验内容:
1.用编辑软件,输入以下汇编语言源程序:
DATSEGMENT;默认ds段
ADB20;(自定)
BDB15;(自定)
YDB3DUP(0)
ZDB0,0
DATENDS
STASEGMENTSTACK
DW50DUP(?
)
STAENDS
CODSEGMENT
ASSUMECS:
COD,DS:
DAT
STARPROCFAR
PUSHDS
XORAX,AX;AX清零
PUSHAX
MOVAX,DAT
MOVDS,AX
MOVAX,STA
MOVSS,AX
MOVAL,A
MOVZ,AL
MOVZ+1,AL
CALLSUB1;A*A
MOVAL,B
MOVZ,AL
MOVZ+1,AL
CALLSUB1;A*A+B*B
MOVAL,A
MOVZ,AL
MOVAL,B
MOVZ+1,AL
CALLSUB1;A*A+B*B+A*B
ADDWORDPTRY,AX;A*A+B*B+A*B+A*B-->(A+B)^2
ADCBYTEPTR[Y+2],0
RET
STARENDP
SUB1PROC
MOVAL,Z
MOVAH,Z+1
MULAH
ADDWORDPTRY,AX
ADCBYTEPTR[Y+2],0
RET
SUB1ENDP
CODENDS
ENDSTAR
2.通过编译,连接形成可执行文件。
3.用DEBUG将可执行文件调入,并进行调试。
(1)用D命令观察数据区在内存中的具体内容,记录单元A和B的具体地址。
(2)用U命令对目标代码反汇编,观察反汇编后的结果.注意发现源程序的起始
位置,并记录这个起始地址。
(3)用T命令作单步跟踪调试.比较每条指令执行后的结果和原来的理解是否
一致。
得出程序运行的结果:
它们是写在什么单元,具体内容是什么;并判断结果是否正确。
(4)用E命令修改单元A,B的内容,重新执行程序,并记录结果。
(5)退出DEBUG。
三、预习题:
1.熟悉常用的DEBUG命令。
2.阅读并分析程序的功能。
答:
程序实现了(A+B)^2的功能。
3.若SS=2000H,SP=FFFFH,向堆栈中压入4字节数据后,如何用D命令显示压入堆栈的内容?
答:
使用指令“d2000:
0000”即可显示压入堆栈的内容,因为SP+1会溢出,所以变成0000。
四、实验过程
a.
通过masm和link命令使得程序编译链接成功。
b.
进入debug中,用u命令查看反编译结果。
得出A的地址为:
076A:
0000,值为14H,即十进制的20D;B的地址为:
076A:
0001,值为0FH,即十进制的15D。
Y的偏移地址为0002H,Z的偏移地址为0005H。
DATA段基地址为076AH。
SUB1子程序段入口地址为003F。
c.
用e命令将A地址和B地址内的值由2AH,32H改为23H,24H,通过d命令重新查看A地址,B地址下的数值,发现改变成功。
d.
利用t命令单步调试,可发现,每一步程序的执行,会与寄存器及存储器的内容的变化是一致的。
e.
退出debug。
五、实验总结
由于之前上《操作系统》时,零散地学过一些汇编相关的内容,所以关于masm、debug的基本指令的使用还是比较熟悉的,在做实验一的整个过程中也是比较轻松。
也希望自己能保持着这种轻松的状态去应对接下来的实验!
实验二分支、循环程序设计
一、实验目的
1.开始独立进行汇编语言程序设计;
2.掌握基本分支,循环程序设计;
3.掌握最简单的DOS功能调用。
二、实验内容
1.安排一个数据区,内存有若干个正数,负数和零。
每类数的个数都不超过9。
2.编写一个程序统计数据区中正数,负数和零的个数。
3.将统计结果在屏幕上显示。
4.(选做题)统计出正奇数、正偶数,负奇数、负偶数以及零的个数。
三、预习题
1.十进制数0~9所对应的ASCII码是什么?
如何将十进制数0~9在屏幕上显示出来?
答:
0~9分别对应ASCII码的30H~39H。
因为屏幕上显示的数字是ASCII码,所以为了将十进制数0~9显示在屏幕上,需在原有的十进制数值基础上加上30H即可。
2.如何检验一个数为正,为负或为零?
答:
本实验中,判断正、负或零是直接用CMP命令和0比较,然后用je、jg、jl等命令进行判断为正、负或零。
四、实验流程图
五、实验源代码
;*********************************************************************************************
;*作者:
LQ*
;*日期:
2017/11/20*
;*功能:
*
;*编写一个程序统计数据区中正偶数,正奇数,负奇数,负偶数和零的个数*
;*********************************************************************************************
assumecs:
code,ds:
data
datasegment
;在db数据区,假定数字大小均在-128~127之间,故每个数字用一个字节去存储
db-8,-10,-6,-5,-2,-55;给定6个负数,其中4个偶数,2个奇数
db4,2,3,78,89,56;给定6个正数,其中4个偶数,2个奇数
db0,0;给定2个零
db'$';设定一个结束符
dataends
codesegment
s1:
db5dup(0);在代码段设置一块空间用于存储统计的最终数值
db'PositiveOdd:
','$';在代码段开出一块空间用于存储显示数据的字符串
db'PositiveEven:
','$'
db'NegativeOdd:
','$'
db'NegativeEven:
','$'
db'Zero:
','$'
start:
movax,data
movds,ax
xordi,di
callmain
main:
moval,[di]
cmpal,'$'
jeshow
cmpal,00H
jgabove0;带符号数的大于比较
cmpal,0
jlbelow0;带符号数的小于比较
jmpequal0
below0:
movbl,2
movah,0
idivbl
cmpah,0
jenagative_even
movax,cs
movcx,ds
movds,ax
movsi,offsets1
incbyteptr[si+2];负奇数
incdi
movds,cx
callmain
nagative_even:
;负偶数
movax,cs
movcx,ds
movds,ax
movsi,offsets1
incbyteptr[si+3]
incdi
movds,cx
callmain
above0:
movbl,2
movah,0
idivbl
cmpah,0
jepositive_even
movax,cs
movcx,ds
movds,ax
movsi,offsets1
incbyteptr[si];正奇数
incdi
movds,cx
callmain
positive_even:
;正偶数
movax,cs
movcx,ds
movds,ax
movsi,offsets1
incbyteptr[si+1]
incdi
movds,cx
callmain
equal0:
movax,cs
movcx,ds
movds,ax
movsi,offsets1
incbyteptr[si+4]
incdi
movds,cx
callmain
show:
;显示数据
xordi,di
movax,0B800H
moves,ax
movax,cs
movds,ax
movsi,offsets1
addsi,5
movdx,0
movbx,0
jmpprint
print:
movcl,[si]
cmpcl,'$'
jeprint_data
movbyteptres:
[di],cl
incdi
movbyteptres:
[di],07H;07H~代表颜色为黑底白字
incdi
incsi
jmpshortprint
print_data:
;打印记录存储的数据值
pushsi
movsi,offsets1
movcl,[bx]
addcl,48
movbyteptres:
[di],cl
incdi
movbyteptres:
[di],71H;71H~代表颜色为白底蓝字
cmpdx,640
jeending
adddx,160
movdi,dx
popsi
incsi
incbx
jmpprint
ending:
movax,04c00H
int21H
codeends
endstart
六、实验过程及解释
本次实验要求统计数据区内正奇数、正偶数、负奇数、负偶数、零的个数,首先将数据区的数值与0比较,按数字的正、负或零的特性分别跳转至处理正数的子程序段、处理负数的子程序段、处理零的子程序段。
其中,在处理正、负数的子程序段,对于正负数进行带符号的除二运算,通过判别余数是否为零判别该数是偶数还是奇数,并且判别后将各个对应的
正奇数、正偶数、负奇数、负偶数、零的个数进行统计。
程序在统计完所有类型的数的个数后,会向显存中写入数字,将统计好的数值以可视化形式呈现出来。
编译运行程序结果如下:
a.
通过masm和link命令使得程序编译链接成功。
b.
由运行结果可看到与数据区设置的正奇数、正偶数、负奇数、负偶数、零的个数一致。
七、实验总结
这次实验相较于第一次实验而言,程序需要自己独立设计并且首次涉及到了向屏幕打印数据的程序编写。
为了充分理解向屏幕打印数据的细节方面,我没有选择中断的调用去打印数据,而是自己往显存中直接写入数据并且在屏幕上呈现。
为了编程实现字符向屏幕端的打印,我需要理解显存的数据存储,如一个ASCII码在屏幕端的显示需要两个字节,屏幕通常一行是显示80个字符,也即一行对应160个字节,同时要使得数据呈现时比较美观,还需要自己设计换行等数值的运算,这些都花了我很多时间去调试,不过这也使得我更完整地理解了显存的工作原理,为之后实验打下了基础。
实验三代码转换程序设计
一、实验目的
1.掌握几种最基本的代码转换方法;
2.运用子程序进行程序设计。
二、实验内容
1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来。
2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明。
3.对输入要有检错措施,以防止非法字符输入,并有适当的提示。
4.将整个程序分解为若干模块,分别用子程序实现.在报告中要给出模块层次图。
三、预习题
1.如何将输入的两个字符(0~9)变为十进制或二进制数?
答:
输入的字符0~9是ASCII码表示的,对应于30H~39H,通过减去30H,可以转换为相应的二进制数。
2.如何将选出的最小值(二进制或十进制)变为ASCII码再进行显示?
答:
由于在数据区存储的最小数的数值为二进制数,同时要以十进制易于读的形式转化为ASCII码并显示,需要进行除十取商及取余运算,并将取出的二进制形式的商、余数加上30H,转化为对应的ASCII码值。
3.你觉得采用二进制运算还是十进制运算更适合于这个实验?
答:
由于存储器、寄存器中存储的数据形式都是二进制形式的,所以我觉得采用二进制运算更适于本实验,我在程序的设计、编写中也是采用了二进制运算。
四、程序流程图
a.模块层次图
b.完整程序流程图
五、程序源代码
;******************************************************************************
;*作者:
LQ*
;*日期:
2017/11/22*
;*功能:
*
;*输入若干两位十进制数,寻找最小值,并打印至屏幕(默认十进制数均为正数)*
;******************************************************************************
assumecs:
code
datasegment
db'WrongInput!
','$'
db'','$'
;前两行字符串,用于向屏幕打印发生错误时的字符串
db127,0,0;用于存储输入的数字,并且于首位存储着最小的数值
dataends
codesegment
message:
db'Theminimumnumis:
','$';用于最后向屏幕打印最小值的字符串
start:
movax,data
movds,ax
xorsi,si
movdi,1AH;1AH对应着存储数字的区域
main:
movah,0;int16h0编号功能是从键盘缓冲区读取一个键盘值输入
int16h
;结果ah存储扫描码,al存储ascii码值
cmpah,1cH;1ch为回车键的扫描码,一旦按下回车表示程序输入结束
jeprint_prog1
cmpah,39H;空格键的扫描键,作为两个十进制数之间的分隔符
jecompare
cmpah,02H
jberror
cmpah,0BH
jaerror
callshow
addsi,2
jmpshortmain
show:
incdi
movdx,0b800H;将输入的字符串打印至屏幕
moves,dx
movbyteptres:
[si],al
movbyteptres:
[si+1],07H
subal,30h
mov[di],al
ret
compare:
movdx,0b800H;将输入的字符串打印至屏幕
moves,dx
movbyteptres:
[si],al
movbyteptres:
[si+1],07H
addsi,2
moval,[di-1]
movbl,10
mulbl
addal,[di]
cmpal,[di-2]
jbminimum
movdi,1AH
jmpfarptrmain
minimum:
mov[di-2],al
movdi,1AH
jmpfarptrmain
print_prog1:
;作为中转,因为print_prog程序段超出了je跳转的范围
jmpprint_prog
error:
;调用第10号中断的2号子程序
movah,2;置光标
movbh,0
movdh,10;dh中放行号
movdl,35;dl中放列号
int10h
movdx,0;ds:
dx指向字符串的首地址
movah,9;使用int21h号中断例程的9号子程序
;功能为在光标位置显示字符串提供要显示的字符串的地址作为参数
;要显示的字符串需用'$'作为结束符
int21h
movcx,10H;设置一个空循环,用于保持错误的提示一段时间
empty:
loopempty
movah,2;置光标
movbh,0
movdh,10;dh中放行号
movdl,35;dl中放列号
int10h
movdx,0DH;ds:
dx指向字符串的空字符串地址
movah,9;使用int21h号中断例程的9号子程序
;功能为在光标位置显示字符串提供要显示的字符串的地址作为参数
;要显示的字符串需用'$'作为结束符
int21h
jmpfarptrmain
print_prog:
xordi,di
adddi,160;在屏幕的第二行打印输出最小值
movax,0B800H
moves,ax
movax,cs
movds,ax
movsi,offsetmessage
movdx,0
movbx,0
jmpprint
print:
movcl,[si]
cmpcl,'$'
jeprint_data
movbyteptres:
[di],cl
incdi
movbyteptres:
[di],07H;07H~代表颜色为黑底白字
incdi
incsi
jmpshortprint
print_data:
;打印记录存储的数据值
movax,data
movds,ax
pushsi
movsi,1AH
movcl,[si];取出最小数的数值
movch,0
movax,cx;因为该数值在内存中是以十六进制存在的,要转化为易于理解的ascii码十进制的形式,需要进行除十取商和取余操作
movbl,10
divbl
movcl,al;获取除十取商后的值即十位上的数值并打印
addcl,48
movbyteptres:
[di],cl
incdi
movbyteptres:
[di],71H;71H~代表颜色为白底蓝字
incdi
movcl,ah;获取除十取余后的值即个位上的数值并打印
addcl,48
movbyteptres:
[di],cl
incdi
movbyteptres:
[di],71H;71H~代表颜色为白底蓝字
ending:
movax,4c00H;最终程序运行结束
int21H
codeends
endstart
六、实验过程及解释
1.本实验已完成的功能是:
a.每次输入一个两位十进制数,按下空格后,会在存储最小值的数据区将刚输入的数值与当前的最小数值进行比对,并时刻在数据区存储当前的最小数。
如果想要向屏幕打印当前所有输入的数字中的最小数的数值时,只需按下回车键,会将当前的最小值打印至屏幕。
b.如果按下错误的按键,屏幕中央会打印出输入错误的提醒,并且这个提醒只会显示几秒钟,类似于弹窗效果,真正起到了提示作用。
2.程序调试结果:
a.
通过masm和link命令使得程序编译链接成功。
b.
正确输入的时候,在此例中,输出了最小数为02,其中02数字的显示为白底蓝字。
c.
输入错误时,会在屏幕中间弹出“wrongInput!
”的警告,警告保持几秒后自动消失。
七、实验总结
本次实验,相较于上一个实验又是一个难度的提升,其中如何得到按键的值,并向屏幕打印出来对应的按键值,还需要了解按键中断触发的工作原理,而这一块在课堂上老师讲解得很浅,还需要自己去查阅相关的资料。
本实验中,我在研读了王爽的《汇编语言》后选中了int16中断的0号功能,关于此功能的调用与使用我也是花了一些时间去琢磨,但此功能在之后的几个实验中都有着极其重要的意义。
此外,还有如何找到最小值,如何在按下不相关按键后提示错误输入并且只显示几秒,这些都用到了一些编程的小技巧,而这些小技巧都是我自己一点一点思索出来的,虽然功能很简单,但是在我看来,这些都是很有趣、很让我满足的。
实验四子程序设计
一、实验目的:
1.进一步掌握子程序设计方法;
2.进一步掌握基本的DOS功能调用。
二、实验内容:
1.从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入。
2.统计检查每个学生的名次。
3.将统计结果在屏幕上显示。
4.为便于观察,输入学生数目不宜太多,以不超过一屏为宜.输出应便于阅读.尽可能考虑美观。
5.输入要有检错手段。
三、预习题:
1.如何确定一个学生在这门科目中的名次?
答:
此程序显然属于排序问题,从简单的排序算法思考,我首先选定使用冒泡排序算法或是插入排序算法,由于插入排序的特性就如同它所介绍的一样--我们在玩纸牌时,每一次抓牌前的纸牌都是排好序的,每一次插牌后也都是排好序的,按照这个特性去设计程序,可以很好地去贴合程序的设计。
于是最后我选定插入排序去确定学生在科目中的名次。
2.你觉得输入结束后,采用什么方法进行比较以得到学生的名次最为简单?
答:
因为本实验我所采取的是插入排序,所以最终输入结束后就已经得到了最终学生的名次,所以输入结束后无需再采用别的算法去确定学生名次。
3.准备好模块层次图。
4.给出输出显示的形式。
答:
逐行显示,每行依次显示出名次、学号、成绩。
四、程序设计流程图
五、程序源代码
;**************************************************************************************************
;*作者:
LQ*
;*日期:
2017/11/23*
;*功能:
*
;*输入若干两位十进制数,对应着学生的科目成绩,按照科目成绩进行排序*
;******************