四川大学微机原理实验报告.docx
《四川大学微机原理实验报告.docx》由会员分享,可在线阅读,更多相关《四川大学微机原理实验报告.docx(29页珍藏版)》请在冰豆网上搜索。
四川大学微机原理实验报告
微机原理实验报告
学院:
专业班级:
姓名
学号
实验一汇编语言编程基础
汇编语言程序上机操作和调试训练
一.功能说明
运用8086汇编语言,编辑多字节非压缩型BCD数除法的简单程序,文件名取为*.ASM。
运用MASM﹒EXE文件进行汇编,修改程序中的各种语法错误,直至正确,形成*.OBJ文件。
运用文件进行连接,形成*.EXE文件。
仔细阅读和体会DEBUG调试方法,掌握各种命令的使用方法。
运用DEBUG。
EXE文件进行调试,使用单步执行命令—T两次,观察寄存器中内容的变化,使用察看存储器数据段命令—D,观察存储器数据段内数值。
再使用连续执行命令—G,执行程序,检查结果是否正确,若不正确可使用DEBUG的设置断点,单步执行等功能发现错误所在并加以改正。
二.程序流程图
设置被除数、商的地址指针
设置单位除法次数计数器
取被除数一位作十进制调整
作字节除法、存商
N被除数各位已除完
Y
显示运算结果
结束
三.程序代码
修改后的程序代码如下:
DATASEGMENT
ADB9,6,8,7,5
BDB5
CDB5DUP(0)
NEQU5
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,ES:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVES,AX
CLD
LEASI,A
LEADI,C
MOVCX,N
MOVAH,0
LP1:
LODSB
AAD
DIVB
STOSB
LOOPLP1
MOVCX,N
LEADI,C
LP2:
MOVDL,[DI]
ADDDL,30H
MOVAH,2
INT21H
INCDI
LOOPLP2
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
四.实验感想和收获
通过这次试验,我对微机原理上级试验环境有了初步的认识,可以较为熟练地对汇编语言进行编译,汇编及连接,同时也学会了用DEBUG调试程序,收获很大。
在这次试验中我也遇到了一些困难。
在刚开始我发现自己无法打开,计算机提示是由于版本不兼容。
我这才想起来我的操作系统是64位的,和该软件版本不兼容。
不过我并没有放弃,经过我的摸索之后,我发现用DOSBOX这个程序可以解决我的电脑运行不了该程序的问题。
在解决了第一个难题后,我开始着手改正试验中的语法错误和逻辑错误,但是无论我怎么修改却始终都无法通过编译,并且基本上每句话都有编译错误。
根据我多年编程的经验来看,这应该是中文输入法在搞鬼,之后我耐心地把程序重新输了一遍,果然通过了编译,并且之后的连接也进行的很顺利。
在用DEBUG调试时发现得出的结果也很正确。
尽管这次的实验内容非常简单,仅仅是教会我们一些基本的操作,但我却明显感觉到了汇编语言和C语言等高级语言所不同的地方。
越是底层,基础的东西就越不人性化,用C语言一行代码就能实验的功能在汇编语言中可能要花上数十行。
看来汇编语言的学习不是几周就能速成的,必须要有长年累月的积淀才能掌握。
实验二设计汇编语言程序
一.功能说明
练习1.实验题目:
编程计算下列表达式:
A=90,B=-70,C=5,Y均为有符号数,计算Y=2×(A+B)+(A×C)÷5
要编写一些稍微复杂的程序,我们会遇到一段程序被反复执行,这样,我们会用到LOOP指令。
使用该指令时,需在CX中装入循环次数。
练习2.码转换程序设计
编制程序,把十进制数15786转化成二进制数。
提示:
15786=1×10×10×10×10+5×10³+7×10²+8×10+6,循环CX=5
练习3.编制程序,从键盘输入最多5个数,求他们的和,存入SUM。
练习4.用“冒泡“法对一组数300,250,280,240,260,按从小到大的顺序排列。
提示:
用冒泡的方法对一组数据元素排序,它的基本方法是:
将相邻的两个元素通过比较进行排序,通过多次,多遍的邻元素排序,实现整个一组数的排序。
对于5(N)个元素,整个排序通过4遍(=N-1)邻元素排序完成。
每一遍的排序由若干次邻元素的排序组成。
4遍排序中,邻元素的排序依次为4,3,2,1遍。
完成第一遍排序后,最大数沉底,已经到达它应占据的位置,不需要参加下一遍的排序。
外循环的次数为CX=4次(N-1),内循环的次数为4,3,2,1(DECCX)
排序遍数
本遍排序前
第一次排序后
第二次排序后
第三次排序后
第四次排序后
1
300,250,280,240,260
250,300,280,240,260
250,280,300,240,260
250,280,240,300,260
250,280,240,260,300
2
250,280,240,260,300
250,280,240,260,300
250,240,280,260,300
250,240,260,280,300
3
250,240,260,280,300
250,240,260,280,300
240,250,260,280,300
4
240,250,260,280,300
240,250,260,280,300
实验要求:
1.编制程序,从键盘输入300,250,280,240,260这五个数,并思考如何输入任意五个数,五个数可以有一位数,二位数,三位数,四位数,五位数,混合输入比较大小;
2.对这组数用冒泡法进行排序,并输出原始数据及排序后数据,两两数据之间用空格分隔;
3.利用DEBUG调试工具,用D0命令,查看排序前后,内存数据的变化,以及会用调试命令查看程序运算中寄存器中的值;
4.去掉最大和最小的两个值,求出其余值的平均值,并输出最大值,最小值和平均值;
5.用压栈PUSH和出栈POP指令“先进后出”的特点,设计算法将平均值按位逐个输出(即输出263);
6.用移位指令将平均值以二进制串的形式输出。
7.设计程序要有模块化的思想,用子程序实现不同的功能;
所有数据输出前要用字符串的输出指令,进行输出提示(如:
zuidazhishi:
300等),所有数据结果能清晰地显示在电脑屏幕上。
二.程序流程图
三.程序代码
练习一:
DATASEGMENT
ADB90
BDB-70
CDB5
YDW
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVBL,A
MOVCL,B
ADDBL,CL;A+B
MOVAL,02H
IMULBL;2*(A+B)
MOVBX,AX
MOVAL,A
MOVCL,C
IMULCL;A*C
IDIVCL;A*C/5
ADDAX,BX
MOVY,AX
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
练习二:
DATASEGMENT
ADW15786
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVBX,A
MOVCX,16
LEFT:
TESTBX,8000H
JNZL1;当首位为1,执行L1
MOVDL,'0';输出‘0’
MOVAH,02H
INT21H
SHL:
SHLBX,1
LOOPLEFT
MOVAX,4CH
INT21H
L1:
MOVDL,'1';输出‘1’
MOVAH,02H
INT21H
JMPSHL
CODEENDS
ENDSTART
运行结果:
练习三:
DATASEGMENT
SUMDW
HEHEDB,,,,
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
LEASI,HEHE
MOVBL,0
MOVCX,5
LOOP1:
MOVAH,01H
INT21H
SUBAL,30H
MOV[SI],AL
INCSI
LOOPLOOP1
MOVCX,5
MOVAX,0
SUBSI,5
LOOP2:
ADDAL,[SI]
AAA
INCSI
LOOPLOOP2
MOVBX,AX
MOVSUM,AX
MOVDL,BH
ADDDL,30H
MOVAH,2
INT21H
MOVDL,BL
ADDDL,30H
MOVAH,2
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
运行结果:
冒泡排序法程序:
DATASSEGMENT
SHURUDB'QINGSHURU5GESHUJU',13,10,'$'
SHU1DB4,,3DUP()
SHU2DB4,,3DUP()
SHU3DB4,,3DUP()
SHU4DB4,,3DUP()
SHU5DB4,,3DUP()
AVERDB3DUP()
SHUCHUDB'PAIXUHOUDESHUJUSHUNXUSHI',':
','$'
MAXDB'ZUIDAZHISHI',':
','$'
MINDB'ZUIXIAOZHISHI',':
','$'
AVERAGEDB'PINGJUNZHISHI',':
','$'
CHUSHUDB100,10
HEDW
STR1DB16DUP(30H)
STR2DB'PINGJUNZHIDEERJINZHICHUANSHUCHU',':
','$'
DATASENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS
START:
MOVAX,DATAS
MOVDS,AX
MOVES,AX
LEADX,SHURU;显示QINGSHURU5GESHUJU:
MOVAH,9
INT21H
MOVCX,5;输入五个数字
MOVSI,0
INPUT:
LEADX,[SHU1+SI];输入要排序的原始数据
MOVAH,10
INT21H
MOVDL,10;输入后换行
MOVAH,2
INT21H
ADDSI,5;指针加5,指向下一个变量
LOOPINPUT
CLD
MOVCX,4;设定排序外循环次数
A:
MOVBP,0
PUSHCX;外循环次数入栈
PX:
PUSHCX
MOVCX,3
LEASI,[SHU1+BP+2];逐位比较两个数大小
LEADI,[SHU1+BP+7]
REPZCMPSB
JBB;如果小于直接比较下一个数,否则两个数对换位置
MOVCX,3
Jh:
MOVAL,SHU1[BP+2]
XCHGAL,SHU1[BP+7];将两个字节对换位置,循环3次即完成这两个数的交换
XCHGAL,SHU1[BP+2]
INCBP
LOOPJh
SUBBP,3
B:
ADDBP,5;指向后面两个数字
POPCX
LOOPPX
POPCX;外循环次数出栈
LOOPA
LEADX,SHUCHU;输出字符串'PAIXUHOUDESHUJUSHUNXUSHI:
'
MOVAH,9
INT21H
MOVCX,5
MOVSI,2
OUTPUT:
PUSHCX;计数器入栈实现循环嵌套
MOVCX,3
L:
MOVAL,[SHU1+SI];输出排序后的5个数字
MOVDL,AL
MOVAH,2
INT21H
INCSI
LOOPL
MOVDL,2CH
MOVAH,2
INT21H
ADDSI,2
POPCX;计数器出栈
LOOPOUTPUT
MOVDL,10
MOVAH,2
INT21H
MOVDL,0DH
MOVAH,2
INT21H
LEADX,MAX;输出字符串'ZUIDAZHISHI:
'
MOVAH,9
INT21H
MOVCX,3
MOVSI,2
D:
MOVDL,[SHU5+SI];输出最大值
MOVAH,2
INT21H
INCSI
LOOPD
MOVDL,10;换行
MOVAH,2
INT21H
MOVDL,0DH
MOVAH,2
INT21H
LEADX,MIN;输出字符串'ZUIXIAOZHISHI:
'
MOVAH,9
INT21H
MOVCX,3
MOVSI,2
E:
MOVDL,[SHU1+SI];输出最小值
MOVAH,2
INT21H
INCSI
LOOPE
MOVDL,10
MOVAH,2
INT21H
MOVDL,0DH
MOVAH,2
INT21H
LEADX,AVERAGE;输出字符串'PINGJUNZHISHI:
'
MOVAH,9
INT21H
MOVCX,3
MOVBX,10;除数10
MOVSI,2
AD:
MOVDX,0
MOVAH,0
PUSHCX
MOVCX,3
ZH:
MOVAL,[SHU2+SI];将十进制数转换为二进制数,为后面求平均值做准备
SUBAL,30H
PUSHAX
MOVAX,DX
MULBX
MOVDX,AX
POPAX
ADDDX,AX
INCSI
LOOPZH;执行3次完成3个十进制数的转换
ADDSI,2
POPCX
ADDHE,DX;将DX的数放在HE中
LOOPAD;循环后得到三个十进制数转换为二进制数之后的相加和
MOVDX,HE;
MOVAX,DX
XORDX,DX
MOVBX,3
DIVBX;除3取平均值,结果将商放在AX中,余数放在DX中
MOVBX,AX;给BX赋值平均数,然后将BX中表示的十进制数转换为对应的字符串
DIVCHUSHU;除100取最高位
ADDAL,30H;转换为ASCII码
MOVAVER,AL
MOVAL,AH
XORAH,AH
DIV[CHUSHU+1];除10取十位
ADDAL,30H
ADDAH,30H;余数就是个位
MOV[AVER+1],AL
MOV[AVER+2],AH
MOVCX,3
MOVSI,0
F:
MOVDL,[AVER+SI];输出平均值
MOVAH,2
INT21H
INCSI
LOOPF
MOVDL,10
MOVAH,2
INT21H
MOVDL,0DH
MOVAH,2
INT21H
LEADX,STR2;输出字符串'PINGJUNZHIDEERJINZHICHUANSHUCHU:
’
MOVAH,9
INT21H
MOVCX,16
MOVSI,0
G:
RCLBX,1;将平均数转换为二进制串
JNCH
ADD[STR1+SI],1;如果不为0就将其加1变成1的ASCII码值
H:
MOVDL,[STR1+SI];将二进制串逐个输出
MOVAH,2
INT21H
INCSI
LOOPG
MOVAH,4CH
INT21H
CODESENDS
ENDSTART
运行结果:
四.实验感想和收获
本次实验相较于第一次难度增大了很多,本人花了大约12个小时才做完。
第一个练习很简单,从编译到连接都是一次通过,在用DEBUG调试发现结果却实正确。
不过在做第二个练习时我遇到了困难,完全没有思路。
当时不知道怎么对一位一位的数据进行操作,在看书的过程中无意中发现了循环指令,我才意识到用SHL指令可以实现这个功能。
第三个联系主要考查我们对中断指令的了解程度,我实现地是一位数的加法,不过后来老师发给了我们他自己编的版本,我感慨道编程真是一门大学问,要考虑到各种各样的功能,人机互动,可能出错的地方。
这都是需要大量的实践积累才行。
在编写冒泡排序法这个程序时我遇到了很多困难。
起初在编写一段循环指令时,未把寄存器CX入宅,所以影响了其他部分的循环次数,导致结果出错。
所以今后编程时一定要把有用的信息入宅,防止被其他指令所改变。
在输出字符时,必须记得把要输出字符的值转变成ASCI码,我期初输出数字时就忘记了这一步导致出了很多差错。
同时在将二进制数转变成BCD吗输出时可以通过除10来实现,将得到的商继续除10,而得到的余数就是个位的值,同理,再次除10得到的余数就是10位。
所以通过适当此处的出发可以将二进制数转变为BCD码。
通过亲身实践这次试验,对汇编语言编程有了初步的认识,也体会到了编程的整个过程。
从读题,设计程序框架到写代码,步步承接,同时将课堂上所学的知识运用起来,在加深理解的同时也发现了自己很多不懂的地方,于是通过自己查资料,问老师终于将程序一步步地调试正确得出期望的结果,那种自豪和满足感油然而生。
第三次实验8253定时器/计数器与接口实验
——乐曲程序
一.功能说明
计算机是如何产生音乐和声响的呢原来在计算机中有一个可编程时间间隔定时器8253,它能根据程序提供的计数值和工作模式,产生各种形状和各种频率的计数/定时脉冲,提供给系统的各个部件使用。
它还可以产生不同频率的脉冲作为扬声器的声源。
在8253定时器内部有3个独立工作的计数器:
Counter0,Counter1,Countre2,每个计数器都分配有一个端口地址,分别是40H,41H,42H。
8253内部还有一个公用的控制寄存器,端口地址为43H,端口地址输入到8253的CS,A1,A0端,分别对三个计数器和控制器寻址。
对8253编程时,先要设定控制字,以选择计数器,确定工作模式和计数值的格式,每个计数器由三个引脚与外部联系,CLK为时钟输入端,GATA为门控制信号输入端,OUT为计数/定时信号输入端。
每个计数器是以倒计数的方式计数,也就是说,从计数初值开始逐次减1,直到减为0为止。
端口地址与计数器的关系:
40H
选中计数器0:
作为定时器为系统日时钟提供计时基准
41H
选中计数器1:
作为定时器使用
42H
选中计数器2:
用来控制扬声器发声
43H
公用的控制器:
分别对三个寄存器和控制器寻址
那么,如何触动扬声器发出声音呢原来PC机的主音箱上装有一只小喇叭,由定时器8253和并行接口芯片8255(可编程外围接口芯片)控制其发声,8255包括三个8位寄存器,两个用于输入功能,一个用于输出功能。
输入寄存器分配的I/O端口地址为60H和62H,输出寄存器分配的I/O端口地址为61H。
8253定时器计数器2连接到扬声器,其电路如下:
8253DRIVER
CLK喇叭
OUT2
8255
PB0GATE2
PB1
装入计数器2的计数初值为533H(896Hz=1331=533H),这样,得到的控制字为B=0B6H,即选中计数器2,读/写,工作方式三(方波发声器),二进制。
计数器2的初始化程序为:
MOVAL,0B6H
OUT43H,AL
1)计算计数值程序段:
MOVDI,给定频率
MOVDX,12H
MOVAX,34DCH
DIVDI
AX中即为计数值。
2)打开扬声器发声,8255PB0,PBI送出高电平:
INAL,61H
ORAL,3
OUT61H,AL
3)关闭扬声器,停止发声:
INAL,61H
ANDAL,0FCH
OUT61H,AL
两只老虎的音频表定义在数据段中,如下:
STACKSEGMENT
DW100DUP()
STACKENDS
DATASEGMENT
MUSICDW2DUP(262,294,330,262);频率表,1231;1231
DW2DUP(330,349,392);345;345;
DW2DUP(392,440,392,349,330,262);565431;565431
dw2dup(294,196,262),0;251;251,0表示结束
TIMEDW10DUP(250*50),500*50,250*50,250*50,500*50;节拍表
DW2DUP(120*50,120*50,120*50,120*50,250*50,250*50)
DW2DUP(250*50,250*50,500*50)
NEQU32;32个音符
DATAENDS
二.实验目的:
学习8253计数器2输出方波信号用以驱动扬声器发声的原理,通过程序设置计数器2的输出波形的频率和延续时间,控制扬声器的音调和发生长短。
三.实验内容:
1.设计程序让微机演奏一段两只老虎的乐曲。
2.思考如何让PC机演奏一遍,两遍以及数遍这段两只老虎的乐曲,并修改程序实现。
四.实验报告:
整理出运行正确的源程序清单(加以中文注释),并给出详细程序流程图。
三.程序代码
DATASSEGMENT
BGDB0AH,0DH,”TWOTIGER:
$”
FREQDW2DUP(262,294,330,262)
DW2DUP(330,349,392)
DW2DUP(392,440,392,349,330,262)
DW2DUP(294,196,262),0;频率表
TIMEDW10DUP(250*50),500*50,250*50,250*50,500*50
DW2DUP(120*50,120*50,120*50,120*50,250*50,250*50)
DW2DUP(250*50,250*50,500*50)
NUMDB3
DATASENDS
STACKSEGMENTPARASTACK'STACK'
DB200DUP();堆栈段定义并分配存储空间
STACKENDS
ASSUMECS:
CODE,DS:
DATA,SS:
STACK
STATPROCF