微机原理软件实验报告文档格式.docx
- 文档编号:7898942
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:59
- 大小:1.09MB
微机原理软件实验报告文档格式.docx
《微机原理软件实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《微机原理软件实验报告文档格式.docx(59页珍藏版)》请在冰点文库上搜索。
MOVAL,Z
MOVAH,Z+1
MULAH
SUB1ENDP
CODENDS
ENDSTAR
2.通过编译,连接形成可执行文件。
3.用DEBUG将可执行文件调入,并进行调试。
1)用D命令观察数据区在内存中的具体内容,记录单元A和B的具体地址。
2)用U命令对目标代码反汇编,观察反汇编后的结果。
注意发现源程序的起始位置,并记录这个起始地址。
3)用T命令作单步跟踪调试。
比较每条指令执行后的结果和原来的理解是否一致,得出程序运行的结果:
它们是写在什么单元,具体内容是什么;
并判断结果是否正确。
在子程序SUB1的入口处设一断点,用G命令执行程序。
在断点处观察堆栈的内容,比较堆栈的内容和程序返回地址是否一致。
4)用E命令修改单元A,B的内容,重新执行程序,并记录结果。
5)用M命令和A命令对程序进行修改:
将主程序中最后两条指令(ADD和ADC)修改为一条CALLSUB1指令,重新执行程序。
6)退出DEBUG。
4.重新使用编辑软件,把源程序最后一句中的STAR去掉。
再次生成可执行文件,并用DEBUG调入内存。
当使用U命令时,显示的结果与前一次(未加STAR)的结果有何不同?
三、预习思考
1.熟悉常用的DEBUG命令。
答:
常用的DEBUG命令如下图表所示。
2.阅读并分析程序的功能。
程序完成的功能是计算两个数的完全平方和,即计算
。
3.若SS=2000H,SP=FFFFH,向堆栈中压入4字节数据后,如何用D命令显示压入堆栈的内?
使用的命令是:
-D2000:
FFFB,即使用段基址加偏移量查看。
四、实验过程
以下由实验截图展现具体的实验过程,截图进行了详细标注,便于阅读。
上图为编译、链接形成可执行文件的过程。
上图展现了进行反编译然后使用D命令查看数据段中A、B值的过程。
上图使用E命令对数据段数据A和B进行了修改,分别由20和15改为了48和64,修改后用D命令进行了查看。
上图演示了如何设置断点。
在SUB1出设置一断点,可以看到程序执行到CALL0003F时中断,各寄存器的值均有显示。
下图为调用子程序SUB1,然后子程序结束,返回主程序前寄存器的值。
可以看到,压入堆栈的IP值弹出,CS:
IP已经指向了下一条语句的地址。
下图中操作实现的功能是将ADD和ADC两条语句替换为CALL语句,通过A命令可以直接修改程序指令,通过插入NOP指令使CPU空闲。
也可以通过M命令拷贝CALLSUB1的机器代码到目的地址,但操作容易出错,原因是源地址和目标地址指令长度不一致。
当重新使用编辑软件,把源程序最后一句中的STAR去掉。
再次生成可执行文件,再次DEBUG时。
当使用U命令时,结果如下图所示。
可以看到,没有ENDSTAR语句,编译器将不知道代码段的入口地址是多少,导致从数据段开始译码,后续译码全部紊乱。
ENDSTAR的作用是指示编译器程序结束,同时告诉编译器程序执行时代码段的入口地址。
五、实验总结
此次实验是微机原理软件实验的第一次实验。
由于平时只是注重理论的学习,没有多少实际编程和调试经验,上机操作还不熟练。
以后需要加强实践。
汇编的调试很重要,有时比写出源代码更重要。
代码是很容易写出的,就看是好是坏,编程技巧是否足够,编程经验是否丰富,但代码的测试,排错确实十分困难的,很难把每一种可能的情况考虑周到,用户的操作也可能出现各种不可预知的情况,往往细小的错误甚至是不明确的地方都可能成为错误的隐患。
这也就是为何软件开发三个之一的人写代码,三分之二的人进行测试。
这次实验我学会了汇编程序的基本调测方法,也体会到汇编的调试和C/C++或者Java调试的差异。
汇编的调试需要深入堆栈和内存区,关心每一地址和每一个指令。
这也体现汇编是底层语言的特点。
实验二分支、循环程序设计
1.开始独立进行汇编语言程序设计;
2.掌握基本分支,循环程序设计;
3.掌握最简单的DOS功能调用。
1.安排一个数据区,内存有若干个正数,负数和零。
每类数的个数都不超过9。
2.编写一个程序统计数据区中正数,负数和零的个数。
3.将统计结果在屏幕上显示。
4.(扩展题)统计出正奇数、正偶数,负奇数、负偶数以及零的个数。
1.十进制数0~9所对应的ASCII码是什么?
如何将十进制数0~9在屏幕上显示出来?
0~9分别对应ASCII码的30H~39H。
欲将十进制数0~9显示在屏幕上,只需要用二进制数0~9分别加上30H即可。
2.如何检验一个数为正,为负或为零?
你能举出多少种不同的方法?
方法有多种,现举出两种。
一是直接用CMP命令和0比较,然后用JZ等命令进行判断;
二是和0相比是否相等,然后用该数(假设为8位)和10000000相与,取出符号位判断,可区分正负。
其余方法大同小异,核心的思想是要么直接和0相比,要么使用逻辑或移位运算,取出符号为进行判断。
(一)、流程图
(二)、源代码
DATASEGMENT
ARRAYDB1,2,3,4,5,6,-1,-2,-3,0,0,0
LENGEQU$-ARRAY;
数组长度
POSIDB?
;
正数个数
NEGTDB?
负数个数
ZERODB?
零的个数
POSIEVENDB?
正偶数
POSIODDDB?
正奇数
NEGTEVENDB?
负偶数
NEGTODDDB?
负奇数
;
用于打印提示的字符串定义
POSICHARDB'
Positive:
$'
NEGTCHARDB'
Negtive:
ZEROCHARDB'
Zero:
EVENCHARDB'
Even:
ODDCHARDB'
Odd:
CRDB0DH,0AH,'
$'
回车换行的ASCII码
DATAENDS
--------------------------------------------------------
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVSI,OFFSETARRAY-1
MOVCL,LENG;
数组长度赋予CL
MOVAL,0
LOP:
CMPCL,0;
循环控制条件:
数组长度减为零
JECALC;
为零则跳出
INCSI
DECCL
MOVBL,[SI];
采用基址加变址寻址
CMPBL,AL;
和零比较
JGISPOSI;
是正数跳转
JEISZERO;
是零跳转
JLISNEGT;
是负数跳转
ISPOSI:
INCPOSI;
正数个数加一
ANDBX,1
ADDPOSIEVEN,BL;
和1与之后的结果加到正偶数中
JMPLOP
ISZERO:
INCZERO
ISNEGT:
INCNEGT;
负数个数加一
ANDBX,1
ADDNEGTEVEN,BL;
和1与之后结果加到负偶数中
JMPLOP
CALC:
MOVAH,POSI
MOVAL,POSIEVEN
SUBAH,AL;
计算正奇数个数
MOVPOSIODD,AH
MOVAH,NEGT
MOVAL,NEGTEVEN
计算负奇数个数
MOVNEGTODD,AH
PRINT:
;
打印正数提示符和正数(奇偶)个数
MOVAH,09H
MOVDX,OFFSETPOSICHAR
INT21H
MOVAH,02H
MOVDL,POSI
ADDDL,30H
MOVDX,OFFSETEVENCHAR
MOVDL,POSIEVEN
MOVDX,OFFSETODDCHAR
MOVDL,POSIODD
MOVDX,OFFSETCR
MOVAH,09H
打印负数提示符和负数(奇偶)个数
MOVDX,OFFSETNEGTCHAR
MOVDL,NEGT
MOVDL,NEGTEVEN
MOVDL,NEGTODD
MOVDX,OFFSETZEROCHAR
MOVDL,ZERO
EXT:
MOVAX,4C00H
CODEENDS
ENDSTART
(三)、实验分析
数据区待统计的数据为:
1,2,3,4,5,6,-1,-2,-3,0,0,0
实验结果如下图所示。
本实验较为简单,意在练习基本的分支、循环结构。
关键的点在于和0比较,区分正负和零,然后在正数和负数中判断奇偶,这里巧妙地使用了和1与之后加和到偶数中,最后利用统计的数的个数减去偶数得奇数的方法。
使得程序更加流畅和简洁,思路也更清晰。
实验中设计好的计算思路是很重要的,汇编的代码由各种跳转和逻辑结构组成,需要考虑代码间的逻辑关系,否则容易出错。
语法错误是很显而易见的,但逻辑错误却不容易发现。
当有大量判断和循环存在时,需要考虑清楚程序跳转的条件和方向,这点和高级语言有较大差异,汇编本质上没有循环和分支,都是通过将IP赋予代码区地址进行跳转实现的,程序员需要自主控制如何跳转,向何处跳转,这点和C/C++中饱受诟病的goto语句处理有些类似。
考虑到实验练习的重点在分支循环结构,此次写代码时暂时没有使用子程序或宏,导致输出部分代码有些过长。
实验三代码转换程序设计
1.掌握几种最基本的代码转换方法;
2.运用子程序进行程序设计。
1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来。
2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明。
3.对输入要有检错措施,以防止非法字符输入,并有适当的提示。
4.将整个程序分解为若干模块,分别用子程序实现。
在报告中要给出模块层次图。
1.如何将输入的两个字符(0~9)变为十进制或二进制数?
输入的字符0~9是ASCII码表示的,对应于30H~39H,通过减去30H,可以转换为相应的计算机数。
2.如何将选出的最小值(二进制或十进制)变为ASCII码再进行显示?
如果采用输入时把ASCII码转换为数字,然后比较数字的大小再输出,那么输出时还需要把数字再次转换为ASCII码。
这是不明智的。
可以直接读入并存储数字的ASCII码,容易比较其大小,然后直接输出ASCII码即可。
3.你觉得采用二进制运算还是十进制运算更适合于这个实验?
采用二进制或者十进制都需要进行ASCII码到数字的转换和其反向转换,换用新的思路可以大大简化编程负担。
即直接使用数字对应的ASCII比较,分别比较十位和个位,最后直接输出字符即可。
(一)流程图
(二)模块层次图
(三)源代码
INPUTDB100DUP(?
MINTMPDB'
9'
-30H,'
-30H;
置最小值的初始值为99
COUNTDB0D
IFERRORDB0D;
用于判断调用输入子程序是否有错
提示信息字符串
WELCOMEDB'
Pleaseinputnumbers:
'
'
OUTTIPDB'
Minimumis:
CRDB0DH,0AH,'
回车换行
各种错误输入提示
ERROR1DB'
ERROR:
Characterisnotvalid!
ERROR2DB'
Numbermustcontainstwodigits!
ERROR3DB'
Numberisempty!
ERROR4DB'
Needseparatechar!
ASSUMECS:
MAINPROCFAR
MOVDS,AX
MOVDX,OFFSETWELCOME;
调用欢迎提示
CALLPRINT
MOVDX,OFFSETCR;
CALLGETNUM;
获取用户输入
CMPIFERROR,0;
判断输入过程是否有错
JNZBACK;
错误则直接返回DOS
MOVDX,OFFSETCR;
CALLFINDMIN;
查找最小数
MOVDX,OFFSETOUTTIP;
调用输出提示
MOVAH,02H
MOVDL,MINTMP;
输出最小值的十位
ADDDL,30H
INT21H
MOVDL,MINTMP[1];
输出最小值的个位
INT21H
BACK:
MOVAX,4C00H;
返回DOS
MAINENDP
获取输入,出口参数为IFERROR,表示是否有错
GETNUMPROC
PUSHAX;
保存现场
PUSHBX
PUSHCX
PUSHDX
PUSHDI
MOVDI,0;
数组偏移地址
MOVCX,0;
标识数字的位数
GETLOOP:
MOVAH,01H;
从键盘读取一个字符
INT21H
CMPAL,0DH;
和回车比较
JEEXIT1;
是回车则结束输入
CMPCX,0;
数字位数为空
JECMPSPACE0
CMPCX,1;
数字位数为1
JECMPSPACE1
CMPCX,2;
数字位数为2
JECMPSPACE2
CMPSPACE0:
CMPAL,20H
JEGETLOOP;
数字位数为0且输入空格则忽略,继续输入
JMPASCBIN;
不是空格就读取该字符
CMPSPACE1:
JEERR2;
数字位数为1且输入空格则位数不是两位数出错
否则读取该字符
CMPSPACE2:
JNEERR4;
数字位数为2后,不输入空格则分隔符错误
XORCX,CX;
输入空格则清零重新计数
JMPGETLOOP
ASCBIN:
SUBAL,30H;
化为二进制数字
JLERR1;
小于则无效字符
CMPAL,9;
和9比较
JGERR1;
大于9则是无效字符
MOVINPUT[DI],AL;
保存输入的数
INCCOUNT;
统计输入的数字个数,为判断是否输入为两位数
INCDI;
向后移动数组
INCCX
JMPGETLOOP
ERR1:
MOVIFERROR,1;
输出错误1
MOVDX,OFFSETERROR1
JMPRETURN
ERR2:
输出错误2
MOVDX,OFFSETERROR2
CALLPRINT
JMPRETURN
ERR3:
输出错误3
MOVDX,OFFSETERROR3
ERR4:
输出错误4
MOVDX,OFFSETERROR4
EXIT1:
MOVBL,COUNT;
判断输入数的个数是否为零
CMPBL,0
JEERR3;
输入数目为0则输出错误并退出
ANDBL,01H;
判断数字是否为两位数
JNEERR2;
输入数字个数为奇数则出错
RETURN:
POPDI;
恢复现场
POPDX
POPCX
POPBX
POPAX
RET
GETNUMENDP
回车换行输出字符串,入口参数为DX
PRINTPROC
PUSHAX
PRINTENDP
查找最小的数子程序
FINDMINPROC
PUSHDI;
保护现场
PUSHCX
MOVDI,-2;
数组下标
MOVCL,COUNT;
把数组长度移入CX
MOVAL,CL
CBW
MOVCX,AX
ADDDI,2
CMPCX,DI;
是否已经比较完毕
JEEXIT2;
如果比较完毕所有数则退出
MOVAH,INPUT[DI];
否则接着比较,移入十位数
MOVAL,INPUT[DI+1];
移入个位数
CMPAH,MINTMP;
比较十位数,MINTMP低地址为十位
JALOP;
如果MINTMP小,则直接比较下一个数
JEHIGHEQU
如果十位数相等,比较个位数,再否则十位大就直接存储
STOMIN:
MOVMINTMP,AH
MOVMINTMP[1],AL
HIGHEQU:
CMPAL,MINTMP[1];
比较个位数
JNBLOP;
个位数比MINTMP大则跳到下一个数
JMPSTOMIN;
否则将当前数写入为MINTMP
EXIT2:
POPCX
POPDI
FINDMINENDP
CODEENDS
ENDMAIN
(四)实验分析
下图是实验输出结果截图。
实验中以空格为分隔符,空格的个数不限制,以回车为输入结束标志符。
对输入的数字进行了位数和范围的严格
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 微机 原理 软件 实验 报告