北邮微机原理软件实验报告 2Word文档格式.docx
《北邮微机原理软件实验报告 2Word文档格式.docx》由会员分享,可在线阅读,更多相关《北邮微机原理软件实验报告 2Word文档格式.docx(30页珍藏版)》请在冰豆网上搜索。
2.源代码
DATASEGMENT
BUFFDW11,12,0,-59,85,78,15,0,-78,0,74,-45,47,0,12,-79;
自定义需要判定的一组数字
COUNTEQU$-BUFF;
得到数据长度
PLUSODB0
PLUSJDB0
ZERODB0
MINUSODB0
MINUSJDB0;
分别用来存几种要求的数字
STRING1DB'
PLUSO,PLUSJ,ZERO,MINUSO,MINUSJ:
'
'
$'
STRINGDB0,'
0,'
;
用来显示结果的字符串
DATAENDS
STACKSEGMENTSTACK'
STACK'
定义堆栈段
DB100DUP(0)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,ES:
DATA,SS:
STACK
BEGINPROCFAR
PUSHDS
XORAX,AX
PUSHAX;
保证返回DOS
MOVAX,DATA
MOVDS,AX
MOVCX,COUNT
SHRCX,1;
相当于对CX中的数除以2
LEABX,BUFF;
得到BUFF的偏移地址
AGAIN:
CMPWORDPTR[BX],0;
将工作指针中的数与零进行比较
JGEPLU
JMPMINUS
PLU:
JZZER;
判定为0
MOVAX,WORDPTR[BX]
MOVDL,2
DIVDL;
将结果除以2
CMPAH,0
JNZPLUJ
INCPLUSO;
正偶数加一
JMPNEXT
PLUJ:
INCPLUSJ;
正奇数加一
MINUS:
IDIVDL
JNZMINJ
INCMINUSO;
负偶数加一
MINJ:
INCMINUSJ;
负奇数加一
JMPNEXT
ZER:
INCZERO;
0加一
NEXT:
INCBX
INCBX;
工作指针加2
LOOPAGAIN
MOVBL,PLUSO
ADDBL,30H;
将统计的数字加上30h变为ASCii码
MOVPLUSO,BL
MOVBL,PLUSJ
ADDBL,30H
MOVPLUSJ,BL
MOVBL,ZERO
ADDBL,30H
MOVZERO,BL
MOVBL,MINUSO
MOVMINUSO,BL
MOVBL,MINUSJ
MOVMINUSJ,BL
LEABX,STRING;
将每个变量统一加到字符串对应位置
MOVCL,PLUSO
MOV[BX],CL
MOVCL,PLUSJ
MOV[BX+2],CL
MOVCL,ZERO
MOV[BX+4],CL
MOVCL,MINUSO
MOV[BX+6],CL
MOVCL,MINUSJ
MOV[BX+8],CL
MOVAH,09H;
打印字符串
MOVDX,SEGSTRING1
MOVDS,DX
MOVDX,OFFSETSTRING1
INT21H
打印结果
MOVDX,SEGSTRING
MOVDX,OFFSETSTRING
RET
BEGINENDP
CODEENDS
ENDBEGIN
3.实验结果分析
实验区待统计的数为:
11,12,0,-59,85,78,15,0,-78,0,74,-45,47,0,12,-79
经过上述代码的编译链接执行后可以得到的结果如下图所示:
经过手动检查发现符合实验的预期结果,则可验证实验的正确性。
六.实验总结
这道题实则是比较基础简单的一道,其核心在于循环结构和对数字判定的比较方法。
对于刚开始编写汇编语言的我而言,还是遇到了不小的挑战。
由于汇编语言它不同于C++的许多复杂特点,确实在刚开始的时候有点无从下手,但是经过反复地读书以及资料的查阅后基本掌握了基本的分支、循环程序的编写,数字的显示等基本功能,即掌握了最简单的DOS功能调用,还是感到很开心而且受益匪浅。
实验三代码转换程序设计
1.掌握几种最基本的代码转换方法;
2.运用子程序进行程序设计.
1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来.
2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明.
3.对输入要有检错措施,以防止非法字符输入,并有适当的提示.
4.将整个程序分解为若干模块,分别用子程序实现.在报告中要给出模块层次图.
1.如何将输入的两个字符(0--9)变为十进制或二进制数?
输入的0——9的字符为ASCII码,只需要将他们减去30H即可得到所需的机器数。
2.如何将选出的最小值(二进制或十进制)变为ASCII码再进行显示?
跟上一个问题类似,再输出时需要将选出的最小值变为ASCII码,方法很简单,即将数字加上30H即可。
3.你觉得采用二进制运算还是十进制运算更适合于这个实验?
采用二进制或者十进制都需要进行ASCII码到数字的转换和其反向转换,相比之下十进制的变换更方便,但换用新的思路可以大大简化编程负担。
即直接使用数字对应的ASCII比较,分别比较十位和个位,最后直接输出字符即可。
四.实验过程
JUDGEMACRO;
用来判定输入数据合不合法的宏
CMPAL,'
0'
JBWRONG
9'
JAWRONG
ENDM
XIANSHIMACROX,Y;
打印两位数XY的宏
MOVAH,02H
MOVDL,X
MOVDL,Y
INPUTMACRO;
输入单个数据的宏
MOVAH,01H
DATASEGMENT;
定义数据段
STRINGDB'
THEMINNUMBERIS:
用于说明的字符串
INPUTISNOTOK!
!
'
0DH,0AH,'
STRING2DB'
PLEASEINPUTNUMBER:
0DH,0AH,'
STRING3DB'
PLEASEINPUTAGAIN.'
STACKSEGMENT'
DB100DUP(0)
START:
MOVDX,DATA
MOVBH,'
用来存最小值的寄存器,并初始化为最大的二位数99
MOVBL,'
MOVAH,09H
MOVDX,SEGSTRING2
MOVDX,OFFSETSTRING2
SHURU:
INPUT;
开始输入数据
CMPAL,20H;
将输入的第一个数与空格进行比较
JZSHURU;
是空格则继续进行输入
CMPAL,0DH;
将输入的数据与回车进行比较,若输入回车则输入结束
JZEXIT
JUDGE;
判定数据是否合法
CALLSHIBI
WRONG:
CALLNOTOK;
输入不合法,报警且再次输入数据
JMPSHURU
EXIT:
XIANSHI0DH,0AH;
输入结束,打印出最小值的结果
XIANSHIBH,BL
JMPENDDOS
ENDDOS:
MOVAX,4C00H;
返回DOS
NOTOKPROC;
打印输出数据不合法并且返回SHURU进行重新输入的子程序
MOVAH,09H
INT21H
MOVDX,SEGSTRING3
MOVDX,OFFSETSTRING3
NOTOKENDP
SHIBIPROC;
比较部分子程序
CMPAL,BH;
将输入的十位与BH中的十位进行比较
JNANEXT
JIXU:
INPUT;
比BH大,则说明输入不是最小数,继续输入
JZXIANG;
判断输入的十位与寄存器中的十位是否相等
MOVBH,AL;
更新寄存器中的最小值
INPUT
JUDGE
MOVBL,AL
XIANG:
再输入第二位进行比较,若更小
CMPAL,BL
JASHURU
MOVBL,AL;
SHIBIENDP
ENDSTART
3.模块层次图
主程序
输入模块
比较模块
输出模块
报错模块
4.实验结果分析
在我的程序设计中,以空格为数据的分隔符,以回车为结束符。
输入回车后会在屏幕上打印最小值的结果。
在输入中如果输入的数据不恰当,会有提示说明输入不合法,并且支持再次输入,其结果图如下。
说明:
空格分隔符,回车为输入完毕确认,当输入不合法字符使,提示输出不正确,并可以继续输入,跟之前输入的数据进行比较。
经过观察后发现,结果完全正确,说明了程序的正确性。
五.实验总结
这次实验学习并运用了子程序进行程序设计。
子程序设计的最重要的地方在于入口参数、出口参数的设计与主程序之间的关系。
还有子程序功能之前应该保护现场。
本实验主要将子程序设计在从键盘输入数字的功能,并设置标志,用于主程序确认输入是否正确。
我在这次实验中由于刚开始写时对子程序的设计理解还不够到位因此遇到了不少困难,主要在于对子程序的调用位置以及怎样从一连串数据输入中找到最小数。
后来查阅了不少资料后意识到了只需要在寄存器中存一个最小值,并初始化为最大值99,然后再输入时反复将寄存器中的值与输入的值进行比较即可并更新寄存器中的数据即可,最后在利用09H中断打印出来就可完成这一实验。
总而言之,这个实验看似简单但是却是很多汇编编程的基础,学会了子程序的编写和调用对今后的编程大有裨益。
实验四子程序设计
1.进一步掌握子程序设计方法;
2.进一步掌握基本的DOS功能调用.
1.从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入.
2.统计检查每个学生的名次.
4.为便于观察,输入学生数目不宜太多,以不超过一屏为宜.输出应便于阅读.尽可
能考虑美观.
5.输入要有检错手段.
1.如何确定一个学生在这门科目中的名次?
其实确定学生在该科目中的名次方法有很多,基本的思路是用一个足够的变量区域存下输入的学生数据信息,然后在对这些数据进行比较。
比较的方法很多,最容易想到的有冒泡排序等,然后最方便的是在记下同学的学号后,依此找出成绩的最大值,往复进行,也可起到排名的作用。
我在这里用到的是与上一个实验类似的思路,每一次寻找成绩中的最小值,再将他的学号和成绩依此压入栈,最后输出时再依此出栈,正好起到了排名的作用。
2.你觉得输入结束后,采用什么方法进行比较以得到学生的名次最为简单?
在汇编语言中使用排序的各种方法其实都很不方便,因为在汇编语言中使用循环是很复杂的,因此沿用上一个实验是最简单好用的方法,每次依此寻找成绩的最小值,并将学号和成绩一起压入栈,最后依次出栈可以实现成绩由高到低排列。
3.准备好模块层次图.
排序模块
显示模块
检错模块
4.给出输出显示的形式.
根据输入的学生的ID和成绩,在输出时按照名次输出,并且显示他的名词序号和学号以及成绩。
ZHUANMACROX;
将数字转换为ASCII码的宏
PUSHAX
PUSHBX
MOVAX,X;
得到该数的十位和个位
MOVBL,10
DIVBL
ADDAL,'
分别加上'
的ASCII码
ADDAH,'
MOVBH,AL
MOVBL,AH
MOVX,BX
POPBX
POPAX
XIANMACROX;
显示单个字符的宏
STRMACROSTRING;
显示字符串的宏
输入单个字符的宏
BUFFDB100DUP(0);
用来存入输入成绩的变量,足够大
STRING1DB0DH,'
INPUTISNOTOK!
thescoreofstudent'
100'
STRING4DB'
No.'
STRING5DB'
therankofallis:
STRING6DB'
student:
STRING7DB'
score:
NUMDW1;
用来存入学生数量的变量
NUM1DW1;
循环中用来记录学生学号的变量
RANKDW1;
表示排名的变量
COUNTDB0;
计数成绩的位数
COUNT1DW1
DB300DUP(0)
ASSUMEDS:
DATA,CS:
CODE,SS:
STACK
START:
LEASI,BUFF;
将工作指针置于BUFF的偏移首地址
LOOP1:
初始化BX
STRSTRING2;
MOVCX,NUM;
显示当前学号
ZHUANCX
XIANCH
XIANCL
XIAN'
:
L3:
INPUT
判断是否为回车,是回车时结束输入并且将结果显示出来
判断输入是否为空格,如果是空格则结束该名同学的成绩输入
JNZL1
L2:
INCNUM;
输入结束,并且NUM加一
CMPCOUNT,1
JZY1
MOV[SI],BH;
在变量中对应位置按学号依此存入学生成绩
MOV[SI+1],BL
JMPY2
Y1:
MOVBYTEPTR[SI],'
MOV[SI+1],BH
Y2:
INCSI;
修改工作指针
INCSI
MOVCOUNT,0
XIAN0DH
XIAN0AH
JMPLOOP1
L1:
CALLJUDGE
CMPDL,0
JNZLOOP1;
继续输入
INCCOUNT
JNZCNT2
修改BH中的十位数
JMPL3
CNT2:
CMPCOUNT,2;
第二位
JNZCNT3
修改BL中的个位数
JMPL3
CNT3:
MOVBH,40H;
三位数
MOVBL,40H
JMPL2
CALLPAIXU;
输入完成后对成绩进行排序
WANLE:
XIAN0DH
STRSTRING5
AGAIN:
MOVCX,NUM1;
将学生数量作为循环次数
CMPCX,0
JNZGOON
ENDDOS:
GOON:
STRSTRING4
MOVCX,COUNT1;
显示当前是第几名
ZHUANCX
POPCX;
将第N名学号出栈
STRSTRING6
XIANCH;
显示他的学号
将第N名的成绩出栈
STRSTRING7
CMPCH,40H;
判断是否为满分的情况
JZFUL
显示他的成绩
LINE:
DECNUM1
INCCOUNT1;
进行下一趟循环
JMPAGAIN
FUL:
STRSTRING3;
直接显示100分
JMPLINE
JUDGEPROC
MOVDL,0
JNBNEXT1
W1:
STRSTRING1
MOVDL,1
JMPOV
NEXT1:
CMPAL,'
JAW1
OV:
RET
JUDGEENDP
PAIXUPROC
EXIT:
DECNUM;
将学生人数减一
MOVAX,NUM
MOVNUM1,AX
LEASI,BUFF
MOVBH,40H
MOVBL,40H
MOVDX,NUM
LOOP2:
CMPNUM,0
JZWANLE
LOOP3:
MOVCL,[SI]
CMPCL,'
?
JZNEXT
CMPCL,BH
JANEXT;
大于等于BH中的十位数
JBI;
小于
MOVCL,[SI+1]
CMPCL,BL
JANEXT
I:
MOVBH,[SI];
修改BX中储存的最小值
MOVBL,[SI+1]
MOVDI,SI
NEXT:
DECDX;
学生人数减一,进行下一趟的比较
CMPDX,0
JNZLOOP3
PUSHBX;
将BX中储存的成绩最小值压入栈
PUSHCX;
保护现场,将CX压入栈
MOVCX,DI
SUBDI,SI;
将DI定位的地址与SI相减
MOVAX,DI
MOVBL,2;
载将相减后的地址除以2
MOVDI,CX;
还原DI
POPCX
MOVRANK,AX;
上面运算后AX中存的数即为当前排名学生的学号
INCRANK
ZHUANRANK
PUSHRANK;
将学号压入堆栈
MOVBYTEPTR[DI],'
将DI所指找出最小值的位置设成跳过符号‘?
’
MOVBYTEPTR[DI+1],'
下一趟
MOVDX,NUM1
MOVBH,40H;
重置BX中的最小值
JMPLOOP2
PAIXUENDP
CODEENDS
ENDSTART
该实验要求按学号依此输入学生成绩,然后对其排名后输出结果显示。
我的程序中,用空格来表征该同学成绩录入完毕,用回车来表示所有同学输入结束,最后依名次由前到后显示同学的学号和成绩。
结果图如下:
经过观察后发现,其结果正确,说明了程序的正确性。
在这个实验中,我进一步掌握了子程序的设计方法,以及中断,宏等汇编语言的特殊功能的使用。
经过一番挫折的尝试后,最终实现了成绩的录入以及排名,能够在屏幕上完美显示学生的成绩情况。
在我的程序中,可以允许输入三位数成绩,这里很巧妙,我用一个40H40H的ASCII码来替代100分,在输出时,如果是这种情况则在屏幕上直接打印结果100分。
我在排名时想到了沿用上一个实验的思路,因此采用了依此寻找最小值的方法,并将它们压入堆栈,在出栈时刚好对应了成绩的由大到小排列,是我程序中排名部分的核心。
当然,我也完成了接错功能,再输入时如果为错误字符,则有提示信息,并且可以支持重新输入。
总之,通过这个实验,我受益匪