1、微机原理软件实验报告学 院:信息与通信工程学院班 级:2012211123班内序号:学生姓名:学 号:实验二 分支,循环程序设计一、实验目的1.开始独立进行汇编语言程序设计;2.掌握基本分支,循环程序设计;3.掌握最简单的 DOS 功能调用.二、实验任务及内容1.安排一个数据区,内存有若干个正数,负数和零。每类数的个数都不超过 9。2.编写一个程序统计数据区中正数,负数和零的个数。3.将统计结果在屏幕上显示。4.(扩展题)统计出正奇数、正偶数,负奇数、负偶数以及零的个数。三、画出程序流程图YNCX=0NYNYN开始初始化判断是否大于等于零读入一个数ZERO+1是否等于零返回 DOS 系统结束M
2、INUS +1PLUS +1四、给出源程序(要求加注释)data segmentbuff dw 1, 2, 0, 0 ,-1 ;数据段,初始化数据count equ $-buffplus db ? ;定义三种数的存储位置zero db ?minus db ?string1 db plus number:,$string2 db zero number:,$string3 db minus number:,$data endsstack segment stack stackdb 100 dup(?)stack endscode segmentassume cs:code,ds:data,es:
3、data,ss:stackbegin:mov ax,datamov ds,axmov cx,countshr cx,1mov dx,0mov ah,0lea bx,buffagain: cmp word ptrbx,0 ;首先和 0 比较jge pluinc ah ;小于零 MINUS+1jmp nextplu: jz zer ;判断是否等于零,等于零 ZERO+1inc dl ;不等于零 PLUS+1jmp nextzer: inc dhnext:inc bx ;下一个数inc bxloop againadd dl,48mov plus,dladd dh,48mov zero,dhadd a
4、h,48mov minus,ahshow:sub dx,dx ;显示模块mov dx,offset string1mov ax,0900h ;送显示指令int 21hmov dl,plusmov ax,0200hint 21hmov dl,0dhint 21hmov dl,0ahint 21hmov dx,offset string2mov ax,0900hint 21hmov dl,zeromov ax,0200hint 21hmov dl,0dhint 21hmov dl,0ahint 21hmov dx,offset string3mov ax,0900hint 21hmov ax,02
5、00hmov dl,minusint 21hmov ax,4c00h ;结束程序int 21hcode endsend begin五、给出程序运行结果(运行结果抓屏保存)data segment 中存入 1,2, 0, 0,-1显示有 2 个 0、2 个大于 0 的数、1 个小于 0 的数,结果正确六、预习题1.十进制数 0 - 9 所对应的 ASCII 码是什么? 如何将十进制数 0 -9 在屏幕上显示出来? 答:对应的 ASCII 码是 30H39H,把 0-9 加上 30H 即可得到对应的 ASCII,送给 DL,再执行 INT 21H 即可显示。2.如何检验一个数为正,为负或为零? 你
6、能举出多少种不同的方法?答:1 先判断是否大于等于零,否则为负数,是则判断是否等于零,否则为整数。2.判断 ZF 标志位,为零则循环左移一直判断,为 1 为负,为 0 为正七、实验总结、建议要求、心得体会之前小学期中已经用汇编语言编写过比较大型的程序,但是是在编译器中运行,比较容易查错,而且显示、输入等功能都是调用硬件实现,因此很多经验不能照搬,遇到了很多问题,我发现汇编语言对程序内部存储器等的利用虽然比 C 语言麻烦,但是都是真正可以控制、可以调用显示的,可以直接 DEBUG 看到内存空间,非常直观。由于在程序中存在很多条件跳转语句,所以需要在最初设计时就考虑好各种分支情况,在画好程序流程图
7、之后,程序的编写工作变得简单了很多,简化了编写代码过程中的思考过程。实验三 代码转换程序设计一、实验目的1.掌握几种最基本的代码转换方法;2.运用子程序进行程序设计.二、实验任务及内容1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来.2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明.3.对输入要有检错措施,以防止非法字符输入,并有适当的提示.4.将整个程序分解为若干模块,分别用子程序实现.在报告中要给出模块层次图.三、画出程序流程图与 MIN 比较,刷新最小值YY显示Y NY输入结束符.N输入空格开始初始化键盘输入两个字符,存储在连续空间检测输入是否正确
8、ERROR!四、给出源程序(要求加注释)注:本程序段中 中断字符为空格 结束字符为回车data segment ;数据段初始化min db 9,9string0 db 0dh,0ah, PLEASE INPUT SOME INTEGERS.DEVIDED with SPACE. STOP with ENTER,0dh,0ah,$string1 db 0dh,0ah, ERROR! PLEASE INPUT AGAIN!,0dh,0ah,$string2 db 0dh,0ah, THE MINEST NUMBER IS:,0dh,0ah,$data endsSTACK SEGMENT STACK
9、 STACKDB 100 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKINPUT PROC NEAR ;输入子函数MOV AH,01H INT 21H ret input endptest1proc near ;测试输入是否为数字子函数cmp al,0jb errorcmp al,9ja errorjmp exiterror:mov al,0 ;输入不为数字返回 0exit:rettest1endpstart:mov ax,datamov ds,axmov dx,offset string0mov ax,0900hint
10、 21hround: ;循环主体call input ;输入第一个数call test1cmp al,00hjz wrong1 ;错误提示mov bh,al ;存储call input ;输入第二个数call test1cmp al,00hjz wrong1mov bl,alcall inputcmp al,0dh ;输入是否结束jz show ;输入结束转移到显示cmp al, ;输入分隔符,开始比较jz comparejmp wrong1wrong1:mov dx,offset string1mov ax,0900hint 21hjmp roundcompare:cmp bx,WORD P
11、TR min ;比较并刷新 MINjb changejmp roundchange: mov word ptr min,bxjmp roundshow: ;显示子函数cmp bx,WORD PTR minjb swapswap: mov word ptr min,bxoutt: mov dx,offset string2mov ax,0900hint 21hmov dl,min+1mov ax,0200hint 21hmov dl,minint 21hmov ax,4c00hint 21hcode endsend start五、给出程序运行结果(运行结果抓屏保存)结果讲解:第一次由于输入了三位
12、数,所以报错;第二次由于输入字母,所以报错;第三次输出正常结果,运行成功。六、回答预习题1. 如何将输入的两个字符(09)变为十进制或二进制数?答:减 30H。2. 如何将选出的最小值(二进制或十进制)变为 ASCII 码再进行显示?答:直接存储输入的 ASCII,不需要转换。如要转换则加 30H。你觉得采用二进制运算还是十进制运算更适合于这个实验?答:二进制运算,直接保存输入的数的二进制编码,直接比较,不需要区分十位个位。七、实验总结、建议要求、心得体会练习了调用子函数,发现子函数调用的 PROC NEAR 必须和子函数名同一行显示,不然程序会报错,还有不能把存储器操作数作为目的操作数,一定
13、要通过寄存器转换。汇编语言有很多需要注意的语法细节,应该多多练习。实验四 子程序设计一、 实验目的1.进一步掌握子程序设计方法;2.进一步掌握基本的 DOS 功能调用.二、实验任务及内容1.从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入.2.统计检查每个学生的名次.3.将统计结果在屏幕上显示.4.为便于观察,输入学生数目不宜太多,以不超过一屏为宜.输出应便于阅读.尽可能考虑美观.5.输入要有检错手段.三、画出程序流程图NY输入是否合理开始提示输入输入子函数单字符输入调用检验子函数调用排序子函数调用显示子函数Y结束输入回车结束四、给出源程序(要求加注释)data segme
14、nt ;数据段初始化buff dw 20 dup(0000h) ;存放成绩buff1 dw 20 dup(31h,32h,33h,34h,35h,36h,37h,38h,39h) ;存放学号count1 db 0 ;存放输入了几个数count2 db 0string0 db 0dh,0ah, PLEASE INPUT SCORES,0dh,0ah,$string1 db 0dh,0ah, ERROR! PLEASE INPUT AGAIN!,0dh,0ah,$string2 db 0dh,0ah, THE RANK :,$string3 db 0dh,0ah, NUMBER :,$data e
15、ndsSTACK SEGMENT STACK STACKDB 100 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKINPUT PROC NEAR ;输入子函数MOV AH,01H INT 21H ret input endptest1proc near ;测试输入是否为数字子函数cmp al,0jb errorcmp al,9ja errorjmp exiterror:mov al,0exit:rettest1endpsave1 proc near ;存储输入的第一个数子函数,存在高位lea si,buffmov cx,
16、0mov cl,count1add si,cxadd si,1mov si,alinc cl ;40mov count1,clretsave1 endpsave2 proc near ;存储输入的第二个数子函数,存在低位lea si,buffmov cx,0mov cl,count1add si,cxdec simov si,alinc cl ;40mov count1,clretsave2 endpcompare proc near ;比较两个数大小并完成交换子函数cmp ax,bxjb changejmp exit0change: mov ch,0lea si,buffadd si,dxm
17、ov si,bxadd si,2mov si,axlea si,buff1add si,dxmov ax,si ;交换成绩同时交换学号add si,2mov bx,simov si,axsub si,2mov si,bxexit0: retcompare endpstart:mov ax,data ;主程序入口mov ds,axmov dx,offset string0mov ax,0900hint 21hmov ax,0round: call input ;输入第一个数call test1 ;测试cmp al,00hjz wrong1 ;错误提示call save1call input ;输
18、入第二个数call test1cmp al,00hjz wrong1call save2call inputcmp al,0dhje list ;输入结束进入排序cmp al, je roundjmp wrong1wrong1: mov dx,offset string1mov ah,09hint 21hmov cl,0mov count1,cljmp roundlist: mov cl,count1shr cl,1mov count2,cldec clmov count1,cljz showorder: mov cl,0 ;冒泡排序法外层循环order1: lea si,buff ;冒泡排序
19、法内层循环mov dh,0mov dl,clshl dl,1 add si,dx ;100mov ax,siadd si,2mov bx,sicall compareinc clcmp cl,count1je order2jmp order1order2: mov cl,count1dec clmov count1,cljnz orderjmp showshow: mov dx,offset string4 ;显示名次mov ah,09hint 21hshow0: mov ah,02hlea si,buff2mov cl,count2show00: inc simov dl,siint 21h
20、dec simov dl,siint 21hinc siinc simov dl, int 21hdec cljnz show00show1: mov dl,0dh ;显示学号int 21hmov dx,offset string3mov ah,09hint 21hmov ah,02hlea si,buff1mov cl,count2show2: inc simov dl,siint 21hdec simov dl,siint 21hinc siinc simov dl, int 21hdec cljnz show2show3: mov dl,0dh ;显示成绩int 21hmov dx,of
21、fset string2mov ah,09hint 21hmov ah,02hlea si,buffmov cl,count2show4: inc simov dl,siint 21hdec simov dl,siint 21hinc siinc simov dl, int 21hdec cljnz show4mov ax,4c00hint 21hcode endsend start五、给出程序运行结果第一次输入三位数提示错误;第二次输出字母提示错误;第三次输入正确,显示名次,学号,分数。六、回答预习题1.如何确定一个学生在这门科目中的名次?答:根据输入成绩进行排序2.你觉得输入结束后,采用什么方法进行比较以得到学生的名次最为简单?答:冒泡排序法3.模块层次图.输入模块 测试输入是否正确模块存储模块键盘输入显示屏显示4.给出输出显示的形式.答:第一行显示名次第二行显示学号第三行显示成绩七、实验总结、建议要求、心得体会本次实验加深了我对汇编语言的理解,更加熟练的掌握汇编语言的用法,熟练了各种DEBUG 的方法,尤其注意在对存储器内容改写时可以用 SI 寄存器,汇编的寄存器数量比较少,不像 C 等语言可以自己定义变量,要注意寄存器的合理利用,不注意的的话可能在程序中随意修改他们的值,导致程序混乱不好调试。总的来说,本次实验十分有意义。显示模块 排序模块