




已阅读5页,还剩43页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
信息与通信工程学院微机原理软件实验报告班级: 2012211103 姓名: 申宇飞 学号: 2012210064 日期: 2014年11月实验一 DEBUG 的使用3一、实验目的3二、实验内容3三、预习思考5四、实验过程6五、实验总结10实验二 分支、循环程序设计11一、实验目的11二、实验内容11三、预习思考11四、实验过程13(一)流程图13(二)源代码14(三)实验分析18五、实验总结18实验三 代码转换程序设计20一、实验目的20二、实验内容20三、预习思考20四、实验过程21(一)流程图21(二)模块层次图21(三)源代码22(四)实验分析26五、实验总结28实验四 子程序设计29一、实验目的29二、实验内容29三、预习思考29四、实验过程30(一)流程图30(二)源代码31(四)实验分析34五、实验总结36实验五 中断程序设计37一、实验目的37二、实验内容37三、预习思考37四、实验过程38(一)流程图38(二)源代码39(三)实验分析45五、实验总结46实验一 DEBUG 的使用一、实验目的1. 掌握汇编程序的编辑、编译、连接和执行的全过程;2. 学习和掌握用DEBUG调试程序的方法。二、实验内容1. 用编辑软件,输入以下汇编语言源程序: DAT SEGMENT A DB 20 B DB 15 Y DB 3 DUP(0) Z DB 0,0 DAT ENDS STA SEGMENT STACK DW 50 DUP(?) STA ENDS COD SEGMENT ASSUME CS:COD,DS:DAT STAR PROC FAR PUSH DS XOR AX,AX PUSH AX MOV AX,DAT MOV DS,AX MOV AX,STA MOV SS,AX MOV AL,A MOV Z,AL MOV Z+1,AL CALL SUB1 MOV AL,B MOV Z,AL MOV Z+1,AL CALL SUB1 MOV AL,A MOV Z,AL MOV AL,B MOV Z+1,AL CALL SUB1 ADD WORD PTR Y,AX ADC BYTE PTRY+2,0 RET STAR ENDP SUB1 PROC MOV AL,Z MOV AH,Z+1 MUL AH ADD WORD PTR Y,AX ADC BYTE PTRY+2,0 RET SUB1 ENDP COD ENDS END STAR2. 通过编译,连接形成可执行文件。3. 用 DEBUG 将可执行文件调入,并进行调试。1) 用 D 命令观察数据区在内存中的具体内容,记录单元 A 和 B 的具体地址。2) 用 U 命令对目标代码反汇编,观察反汇编后的结果。注意发现源程序的起始位置,并记录这个起始地址。3) 用 T 命令作单步跟踪调试。比较每条指令执行后的结果和原来的理解是否 一致,得出程序运行的结果:它们是写在什么单元,具体内容是什么;并判断结果是否正确。在子程序 SUB1 的入口处设一断点,用 G 命令执行程序。 在断点处观察堆栈的内容,比较堆栈的内容和程序返回地址是否一致。4) 用 E 命令修改单元 A,B 的内容,重新执行程序,并记录结果。5) 用 M 命令和 A 命令对程序进行修改:将主程序中最后两条指令 (ADD 和ADC) 修改为一条 CALL SUB1 指令,重新执行程序。6) 退出 DEBUG。4. 重新使用编辑软件,把源程序最后一句中的 STAR 去掉。再次生成可执行文件,并用 DEBUG 调入内存。当使用 U 命令时,显示的结果与前一次(未加 STAR) 的结果有何不同?三、预习思考1. 熟悉常用的 DEBUG 命令。答:常用的DEBUG命令如下图表所示。2. 阅读并分析程序的功能。答:程序完成的功能是计算两个数的完全平方和,即计算。3. 若 SS=2000H,SP=FFFFH, 向堆栈中压入 4 字节数据后,如何用 D 命令显示压入堆栈的内?答:使用的命令是:-D 2000:FFFB,即使用段基址加偏移量查看。四、实验过程1 编译和链接形成可执行文件。a. 用debug命令对程序进行调试1) 用 D 命令观察数据区在内存中的具体内容,记录单元 A 和 B 的具体地址。2) 用 U 命令对目标代码反汇编,观察反汇编后的结果。注意发现源程序的起始位置,并记录这个起始地址。其中第一个红色框框住的076AH表示数据段的段地址,第二个红色方框框住的是A的偏移地址,第三个红色方框框住的是B的偏移地址。D指令后面跟随的是A的地址。黄色方框框住的分别是A和B的数值。3) 用 T 命令作单步跟踪调试。比较每条指令执行后的结果和原来的理解是否 一致,得出程序运行的结果:它们是写在什么单元,具体内容是什么;并判断结果是否正确。在子程序 SUB1 的入口处设一断点,用 G 命令执行程序。 在断点处观察堆栈的内容,比较堆栈的内容和程序返回地址是否一致。在执行子程序之前:第一个红色方框框住的是call SUB1指令的位置和指令的内容。第二个红色方框g指令后面跟随的就是该断点的地址。单步执行后:可以在图中看到第一个红色方框显示的是子程序执行之前执行到的代码的地址。第二个红色方框显示的是子程序开始调用后代码执行的地址。显然此时前一步的CS和IP内容已经压栈,并且CS和IP指向了子程序的地址。4) 用 E 命令修改单元 A,B 的内容,重新执行程序,并记录结果。第一个和第二个蓝色方框框住的是输入要修改内容的地址。第三个蓝色方框表示要查看的内存单元的地址。第一个和第二个绿色方框框住的是修改前后该地址存储的内容。第三个绿色方框表示的是修改后内存内存储的数值情况。5) 用 M 命令和 A 命令对程序进行修改:将主程序中最后两条指令 (ADD 和ADC) 修改为一条 CALL SUB1 指令,重新执行程序。将ADD和ADC指令修改为一条CALL SUB1指令:2 重新执行编译过程:把源程序最后一句中的 STAR 去掉。再次生成可执行文件,再次DEBUG。当使用 U 命令时,结果如下图所示。可以看到,没有END STAR语句,编译器将不知道代码段的入口地址是多少,导致从数据段开始译码,后续译码全部紊乱。END STAR的作用是指示编译器程序结束,同时告诉编译器程序执行时代码段的入口地址。五、实验总结此次实验是微机原理软件实验的第一次实验。上课期间我们更多的是学会单句汇编语言的书写和使用法则,很少深入到程序的底层和内部进行探究和调测。本次实验虽然内容比较简单,更多地涉及到了debug命令的操作和之行,而实际上更多考察了我们对于汇编语言与内存等存储单元的调用和关系。这和高级语言是极其不同的。这次实验我学会了汇编程序的基本调测方法,也体会到汇编的调试和高级语言调试调用的方法是具有很大差别。对于汇编语言程序的调用和调试,需要考虑到内存的每一个单元,在进行子程序调用的时候,还需要照顾到堆栈的进出关系。而高级语言则直接进行语言的书写而不必考虑到底层数据和存储单元的变化。我想这两者的区别,可以通过这次实验得到深刻的体会。实验二 分支、循环程序设计一、实验目的1. 开始独立进行汇编语言程序设计;2. 掌握基本分支,循环程序设计;3. 掌握最简单的 DOS 功能调用。二、实验内容1. 安排一个数据区,内存有若干个正数,负数和零。每类数的个数都不超过 9。2. 编写一个程序统计数据区中正数,负数和零的个数。3. 将统计结果在屏幕上显示。4. (扩展题)统计出正奇数、正偶数,负奇数、负偶数以及零的个数。三、预习思考1. 十进制数 0 9 所对应的 ASCII 码是什么? 如何将十进制数 0 9 在屏幕上显示出来?答:09分别对应ASCII码的30H39H。欲将十进制数09显示在屏幕上,只需要调运DOS 2号功能,入口参数为二进制数09分别加上30H即可。2. 如何检验一个数为正,为负或为零? 你能举出多少种不同的方法?答:方法有多种,现举出两种。CMP命令,将该数与0比较,然后用JZ等命令进行判断;将该数与0相比,若不等则用该数(假设为8位)和10000000相与,取出符号位判断,可区分正负。其余方法大同小异,核心的思想是要么直接和0相比,要么使用逻辑或移位运算,取出符号为进行判断。四、实验过程(一)流程图(二)源代码DATA SEGMENT BUFF DB 100,125,47,56,6,-1,-2,-3,-8,-101,0,0,0;初始数据 COUNT EQU $-BUFF ;数据长度 POSI DB 0 ;正数个数 NEGT DB 0 ;负数个数 ZERO DB 0 ;零的个数 POSIEVEN DB 0 ;正偶数 POSIODD DB 0 ;正奇数 NEGTEVEN DB 0 ;负偶数 NEGTODD DB 0 ;负奇数 ;-用于打印提示的字符串定义 STR DB 0DH,0AH,The original data are : 100,125,47,56,6,-1,-2,-3,-8,-101,0,0,0,0DH,0AH,$ POSICHAR DB 0DH,0AH,The number of positive: $ NEGTCHAR DB 0DH,0AH,The number of negtive : $ ZEROCHAR DB 0DH,0AH,The number of zero : $ EVENCHAR DB Even: $ ODDCHAR DB Odd : $ CR DB 0DH,0AH,$; 回车换行的ASCII码DATA ENDS ;-STACK SEGMENT STACK STACK DB 100 DUP(0)STACK ENDS;-CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK;-START: MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUFF MOV CL,COUNT;数组长度赋予CLLOP: CMP CL,0 ;循环控制条件:数组长度减为零 JE PRINT ;为零则跳出 MOV BL,SI ;采用寄存器寻址 INC SI DEC CL CMP BL,0 ;和零比较 JG ISPOSI ;是正数跳转 JE ISZERO ;是零跳转 JL ISNEGT ;是负数跳转ISPOSI: INC POSI ;正数个数加一 AND BL,1 JZ POSI_EVEN INC POSIODD JMP LOP ISZERO: INC ZERO JMP LOP ISNEGT: INC NEGT ;负数个数加一 AND BL,1 JZ NEGT_EVEN INC NEGTODD JMP LOP ;- POSI_EVEN: INC POSIEVEN JMP LOP NEGT_EVEN: INC NEGTEVEN JMP LOP;- PRINT: MOV AH,09H ;显示原始数据 MOV DL,OFFSET STR INT 21H ;-显示正数、正偶数、正奇数个数-;*正数个数* MOV AH,09H ;显示字符串,打印正数个数提示符 MOV DX,OFFSET POSICHAR INT 21H MOV AH,02H ;显示单个字符,打印正数个数 MOV DL,POSI ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;*正偶数个数* MOV AH,09H ;显示字符串,打印正偶数个数提示符 MOV DX,OFFSET EVENCHAR INT 21H MOV AH,02H ;显示单个字符,打印正偶数个数 MOV DL,POSIEVEN ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;*正奇数个数* MOV AH,09H ;显示字符串,打印正奇数个数提示符 MOV DX,OFFSET ODDCHAR INT 21H MOV AH,02H ;显示单个字符,打印正奇数个数 MOV DL,POSIODD ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;*回车换行* MOV AH,09H ;回车换行 MOV DX,OFFSET CR INT 21H;-显示负数、负偶数、负奇数个数- ;*负数个数* MOV AH,09H ;显示字符串,打印负数个数提示符 MOV DX,OFFSET NEGTCHAR INT 21H MOV AH,02H ;显示单个字符,打印负数个数 MOV DL,NEGT ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;*负偶数个数* MOV AH,09H ;显示字符串,打印负偶数个数提示符 MOV DX,OFFSET EVENCHAR INT 21H MOV AH,02H ;显示单个字符,打印负偶数个数 MOV DL,NEGTEVEN ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;*负奇数个数* MOV AH,09H ;显示字符串,打印负奇数个数提示符 MOV DX,OFFSET ODDCHAR INT 21H MOV AH,02H ;显示单个字符,打印负奇数个数 MOV DL,NEGTODD ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;*回车换行* MOV AH,09H ;回车换行 MOV DX,OFFSET CR INT 21H ;-显示零的个数- MOV AH,09H ;显示字符串,打印零的个数提示符 MOV DX,OFFSET ZEROCHAR INT 21H MOV AH,02H ;显示单个字符,打印零的个数 MOV DL,ZERO ADD DL,30H ;入口参数为数字的ASCII码 INT 21H ;- EXT: MOV AX,4C00H INT 21H;-CODE ENDS END START (三)实验分析数据区待统计的数据为:100,125,47,56,6,-1,-2,-3,-8,-101,0,0,0实验结果如下图所示:本实验较为简单,意在练习基本的分支、循环结构。关键的点在于和0比较,区分正负和零,然后在正数和负数中判断奇偶,与1相与,最后利用统计的数的个数减去偶数得奇数的方法。使得程序更加流畅和简洁,思路也更清晰。五、实验总结实验中设计好的计算思路是很重要的,汇编的代码由各种跳转和逻辑结构组成,需要考虑代码间的逻辑关系,否则容易出错。语法错误是很显而易见的,但逻辑错误却不容易发现。当有大量判断和循环存在时,需要考虑清楚程序跳转的条件和方向,这点和高级语言有较大差异,汇编本质上没有循环和分支,都是通过将IP赋予代码区地址进行跳转实现的,程序员需要自主控制如何跳转,向何处跳转,这点和C/C+中的goto语句处理有些类似。考虑到实验练习的重点在分支循环结构,此次写代码时暂时没有使用子程序或宏,导致输出部分代码有些过长。实验三 代码转换程序设计一、实验目的1. 掌握几种最基本的代码转换方法;2. 运用子程序进行程序设计。二、实验内容1. 从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来。2. 两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明。3. 对输入要有检错措施,以防止非法字符输入,并有适当的提示。4. 将整个程序分解为若干模块,分别用子程序实现。在报告中要给出模块层次图。三、预习思考1. 如何将输入的两个字符(09)变为十进制或二进制数?答:输入的字符09是ASCII码表示的,对应于30H39H,通过减去30H,可以转换为相应的计算机数。2. 如何将选出的最小值(二进制或十进制)变为 ASCII 码再进行显示?答:如果采用输入时把ASCII码转换为数字,然后比较数字的大小再输出,那么输出时还需要把数字再次转换为ASCII码。这是不明智的。可以直接读入并存储数字的ASCII码,容易比较其大小,然后直接输出ASCII码即可。3. 你觉得采用二进制运算还是十进制运算更适合于这个实验?答:采用二进制或者十进制都需要进行ASCII码到数字的转换和其反向转换,换用新的思路可以大大简化编程负担。即直接使用数字对应的ASCII比较,分别比较十位和个位,最后直接输出字符即可。四、实验过程(一)流程图(二)模块层次图(三)源代码DATA SEGMENT BUFF DB 100 DUP(0) MIN DB 9-0,9-0 ;置最小值的初始值为99 COUNT DB 0 ;数组长度 IFERR DB 0 ;输入错误标志,0无错,1有错 ;-提示信息字符串 INPUTTIP DB 0DH,0AH,0DH,0AH,Please input several double-digit decimal numbers separated with ,0DH,0AH,0DH,0AH,and end inputting with Enter.,$ NUMTIP DB 0DH,0AH,0DH,0AH, Your numbers are:,$ OUTTIP DB 0DH,0AH,0DH,0AH, The minimum is :,$ AGAIN DB 0DH,0AH,-Do you want to run the program again (Y/N):,$ LINE DB 0DH,0AH,-,$;-错误输入提示 ERROR DB 0DH,0AH,0DH,0AH,ERROR:,0DH,0AH,Your input must be double-digit decimal numbers.,0DH,0AH,And you must separate every two of them with only one ,.,$DATA ENDS;-CODE SEGMENT ASSUME CS:CODE,DS:DATA MAIN PROC FAR MOV AX,DATA MOV DS,AX MOV DX,OFFSET INPUTTIP ;调用输入提示 CALL PRINT ;-注:数字的存储和比较都是以ASCII码形式REP1:MOV DX,OFFSET NUMTIP ;调用提示 CALL PRINT CALL INPUT ;获取用户输入 CMP IFERR,1 ;判断输入过程是否有错 JZ GOON ;继续 CALL FINDMIN ;查找最小数 MOV DX,OFFSET OUTTIP ;调用输出提示 CALL PRINT MOV AH,02H MOV DL,MIN ;输出最小值的十位 INT 21H MOV AH,02H MOV DL,MIN1 ;输出最小值的个位 INT 21H GOON: MOV DX,OFFSET LINE ;分隔线输出 CALL PRINT MOV DX,OFFSET AGAIN ;调用继续比较提示 CALL PRINT MOV AH,01H ;从键盘读取一个字符 INT 21H CMP AL,59H ;是否是Y JE REP1 ;是,重新输入 CMP AL,79H ;是否是y JE REP1 ;是,重新输入 BACK: MOV AX,4C00H ;返回DOS INT 21HMAIN ENDP;-;输入子过程-出口参数为IFERR,表示是否有错INPUT PROC PUSH AX ;保存现场,将子过程用到的寄存器入栈 PUSH BX PUSH CX PUSH DX PUSH SI MOV SI,0 ;数组下标 MOV CX,0 ;循环计数,三个输入字符为一个小单元 INPUTLOOP: MOV AH,01H ;从键盘读取一个字符 INT 21H CMP AL,0DH ;和回车比较 JE EXIT1 ;是回车则结束输入 INC CX ;输入字符计数 CMP CX,3 ;输入是否为第3n个字符(n=1,2.),即是否为输入分隔符的位置 JE CHECK ;是,则检验分隔符 JMP GETNUM ;不是,则读取输入字符 CHECK:CMP AL,2CH ;输入字符是否为逗号 JNE ERR ;不是,则分隔符错误,进行错误处理 XOR CX,CX ;是,则计数单元清零 JMP INPUTLOOP GETNUM:CMP AL,30H ;和0比较 JL ERR ;小于0则是无效字符,进行错误处理 CMP AL,39H ;和9比较 JG ERR ;大于9则是无效字符,进行错误处理 MOV BUFFSI,AL ;保存输入的数(存储的是ASCII码) INC COUNT ;统计输入的数字个数,为判断是否输入为两位数 INC SI ;向后移动数组 JMP INPUTLOOP ;继续输入ERR: MOV IFERR,1 ;错误处理 MOV DX,OFFSET ERROR CALL PRINT JMP RETURNEXIT1: MOV BL,COUNT ;把数组长度送入BL CMP BL,0 ;判断输入数的个数是否为零 JE ERR ;是0,则输出错误并退出 AND BL,01H ;判断数组长度是否为偶数 CMP BL,0 JNE ERR ;输入数字个数为奇数则出错 RETURN:POP SI ;恢复现场 POP DX POP CX POP BX POP AX RETINPUT ENDP;-;打印显示子过程-入口参数为DXPRINT PROC PUSH AX MOV AH,09H INT 21H POP AX RETPRINT ENDP;-;查找最小数子程序-入口参数为数组地址和数组长度FINDMIN PROC PUSH SI ;保护现场 PUSH AX PUSH CX MOV SI,0 ;数组下标 MOV CL,COUNT ;把数组长度送入CL MOV AL,CL CBW ;将AL的最高位扩展至AH MOV CX,AXLOOP1: CMP CX,SI ;是否已经比较完毕 JE EXIT2 ;是,则退出 MOV AH,BUFFSI ;否,则接着比较,当前数的十位移入AH MOV AL,BUFFSI+1 ;当前数的个位移入AL ADD SI,2 ;数组下标移位至下一个数的十位 CMP AH,MIN ;比较十位数,MIN低地址为十位 JA LOOP1 ;如果MIN小,则直接比较下一个数 JE HIGHEQU ;如果十位数相等,比较个位数,再否则十位大就直接存储 STOMIN:MOV MIN,AH MOV MIN1,AL JMP LOOP1HIGHEQU:CMP AL,MIN1 ;比较个位数 JNB LOOP1 ;个位数比MIN大则跳到下一个数 JMP STOMIN ;否则将当前数写入为MINEXIT2: POP CX POP AX POP SI RETFINDMIN ENDP;-CODE ENDS END MAIN(四)实验分析实验中输入的数字必须是两位十进制数字,每两个数字之间用逗号“,”作为分隔符,且每两个数之间只能有一个分隔符,以回车为输入结束标志符。检错思路:试验中实行对每一个输入字符的实时检测,输入非法则立即停止。为方便检错,试验中每3对输入字符作为一个小单元。判断条件:每个小单元的第1、2个字符必须是09中的一个数字;而第3位必须是分隔符“,”;回车之后对总的输入进行判断,输入数字的个数必须为偶数。以上三种情况囊括了所有可能的格式错误,不满足任何一个条件即出错。实验运行结果截图如下:正确输入:错误输入输入3位数错误输入输入1位数错误输入输入非法字符错误输入分隔符格式不正确五、实验总结总结实验中的关键设计思路如下:1、严格的输入格式检查,严格的输入字符有效性检查。2、以数组方式进行存储,每两个BYTE存储一个输入的两位数,存储格式为字符ASCII码。不进行字符ASCII码到数字的转换。3、比较数字大小时,采用分别比较高位ASCII码和低位ASCII码的方式,从而不用在输入时将字符存储为数字,输出时也不用再进行逆转换。程序效率大为提高。4、为使得程序结构清晰,减小代码耦合度,采用了多子程序的设计方式。把实验任务分为三步:读取输入、找出最小、输出打印,分别以子程序方式实现,主调函数依次调用完成实验任务。实验中比较大小的方式有多种,如何采用更加简洁有效的方式是值得思考的问题。我一开始也不免陷入到比较数字大小的常规方法中,但由于汇编输入具有特殊性,即输入的是ASCII码而非数字的大小,且存在将两个字符进行连接成为两位数的需求,而输出时又需一情况,所以本实验中的数值存储、比较和输出都是用ASCII码。这说明,在实要进行反过程。考虑到ASCII也是可以比较的,且十位数和个位数是可以分别比较的这际的编程中,需要根据具体情况调整一般方法,使得方法更加简洁可行且有效。实验四 子程序设计一、实验目的1. 进一步掌握子程序设计方法;2. 进一步掌握基本的 DOS 功能调用。二、实验内容1. 从键盘上输入某班学生的某科目成绩。输入按学生的学号由小到大的顺序输入。2. 统计检查每个学生的名次。3. 将统计结果在屏幕上显示。4. 为便于观察,输入学生数目不宜太多,以不超过一屏为宜。输出应便于阅读.尽可能考虑美观。5. 输入要有检错手段。三、预习思考1. 如何确定一个学生在这门科目中的名次?答:抽取每个学生的成绩和其他所有学生的成绩进行比较,然后统计比其分数高的学生,得出该学生的名次;通过n次冒泡,将成绩的相对最大值(连带学号)不断往前移动,最后出来的就是一个从高到低的包括学号在内的排名表。本实验采用第二种方式,用冒泡法予以具体实现。2. 输入结束后,采用什么方法进行比较以得到学生的名次最为简单?答:我采用了检错后使用n轮冒泡,将最大值连带学号不断往前移动的方式实现了成绩的排名与学号的对应。3. 准备好模块层次图。4. 给出输出显示的形式。答:程序中使用的数据区的数据单元格式:INFO DB 50 DUP(?);数据检错后的数据存储器6个字节为一个数据单元学号分隔符成绩分隔符31H30H09H36H39H09HINFO2 DB 100 DUP(?);排序后的数据存储器9个字节为一个数据单元学号(字),Tab(09H),成绩(字),Tab(09H),排名(字节ASCII),0AH,0DH学号分隔符成绩分隔符排名换行符31H30H09H36H39H09H31H0AH0DH四、实验过程(一)流程图 (二)源代码DATA SEGMENTINPUTINFO DB 0AH,0DH,PLEASE INPUT THE SCORES:,0AH,0DH,$;BUFC1 DB 50 ;缓冲区第一个字节NUM DB 0 ;缓冲区第二个字节存放输入的字符数BUFC2 DB 50 DUP(0) ;存储用户真正输入的字符INFO DB 50 DUP(0);数据检错后的数据存储器INFO1 DB 0AH,0DH,NO.,09H,SCORES,09H,PAIPING,0AH,0DH;表头INFO2 DB 100 DUP(0);排序后的学号(字),Tab(09H),成绩(字),Tab(09H),排名(字节ASCII),0AH,0DH-9个字节为一项ERROR DB 0AH,0DH,Your input has some error,0AH,0DH,$; DATA ENDS;-STACK SEGMENTDB 100 DUP(0)STACK ENDS;-CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV AX,DATAMOV DS,AXLEA DX,INPUTINFO;使用DOS 9号功能,将提示信息显示在屏幕MOV AH,09HINT 21HMOV DX,OFFSET BUFC1 ;使用DOSA号功能,将输入存到缓冲区BUFMOV AH,0AHINT 21HXOR CX,CX;清空CX,为存储用户实际输入的成绩数量做准备LEA BX,BUFC2LEA DI,INFOCALL CHECK;调用CHECK子程序检测用户的输入是否有误,无误就讲数据转移到INF0区域,并生成相应的学号MOV NUM,CL;将学生数存到NUM;以下为排序过程LEA DI,INFO2MOV DL,CL;DL用于控制冒泡的趟次MOV DH,31H;DH用于表示排名的次序L:DEC DL;冒泡的轮数MOV CL,NUMDEC CL;冒泡的次数MOV CH,0LEA SI,INFOMOV BX,SI;BX存储最高成绩所在的地址单元MAX:ADD SI,6;将SI直到下一个数据单元MOV AX,BX+3;将最高成绩赋给AXCMP AX,SI+3;最高成绩与下一个成绩比较JB JIAOHUAN;下一个成绩高则将下一个数据单元的地址赋给BXJMP LO;否则进行下一个冒泡JIAOHUAN:MOV BX,SILO:LOOP MAXMOV AX,BX;将最大值的数据单元传到INFO2数据区MOV WORD PTRBX,0;并将原INFO数据区最大值清零,为下一次的找最大值做准备MOV DI,AXMOV AX,BX+2MOV WORD PTRBX+2,0MOV DI+2,AXMOV AX,BX+4MOV WORD PTRBX+4,0MOV DI+4,AXMOV DI+6,DHMOV DI+7,0D0AH;添加回车换行符,为显示做准备ADD DI,9;INFO2数据区转移到下一个数据单元,为下一次的数据转移做准备INC DH;看是否完成了所有数据的转移CMP DL,0JA LMOV BYTE PTRDI,$MOV DX,OFFSET INFO1;使用INFO1是因为带上表头显示MOV AH,09HINT 21HMOV AH,4CHINT 21H;-CHECK PROC NEAR;数据合法性检测与数据单元初始化MOV DX,3130H;学号LOOPP:INC CX;统计实际输入的学生成绩数量MOV DI,DX;为INFO数据单元赋学号ADD DX,100H;下一个学号MOV DI+2,09H;为INFO数据单元赋分隔符ADD DI,3MOV AL,BX;检测个位是否合法CMP AL,0JB ERRORSCMP AL,9JA ERRORSMOV AH,BX+1;检测十位是否合法CMP AH,0JB ERRORSCMP AH,9JA ERRORSMOV DI,AX;为INFO数据单元赋成绩ADD DI,2MOV AL,BX+2CMP AL,0DH;检验是否为回车JE EXITRETMOV BYTE PTRDI,09H;分隔符改为tableINC DIADD BX,3;加3去检测下一个输入的数据JMP LOOPP;-EXITRET:MOV BYTE PTRDI,09HMOV BYTE PTRDI+1,$RETERRORS:M
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年【R1快开门式压力容器操作】考试题库及答案
- 2025年公路水运工程试验检测师公共基础试题库及答案(法规与技术标准)
- 2025年监理工程师之交通工程目标控制考试题库含答案a卷
- 桥梁招标课件
- 2025年品牌营销经理招聘面试模拟题与技巧解析
- 2026届安徽省亳州市第三十二中学高三化学第一学期期中联考模拟试题含解析
- 2025年电商运营岗位笔试模拟题及答案解析
- 2025护士资格证考试题库及答案
- 2025年大数据与人工智能课程考试试题及答案
- 2025年旅游管理与规划项目的考试试题及答案
- 小升初测试(试题)-2023-2024学年六年级下册数学苏教版
- 青少年抑郁症的预防和干预策略
- 考公行测言语理解与表达题库之选词填空公考公务员考试省考国考310题(含答案)
- 2021年度计算机审计初级网络培训测试题
- 康复科康复评定表
- 输液反应-完整版
- 【高质量】如何进行有效的校本研修PPT文档
- 水泥生产企业生产安全事故综合应急预案
- 食堂安全培训-课件
- 胆总管结石伴急性胆管炎
- 制度编写书写规范
评论
0/150
提交评论