1、微原软件实验姓 名 学 院 专 业 班 级 学 号 班内序号 实验二 分支,循环程序设计一.实验目的:1.开始独立进行汇编语言程序设计;2.掌握基本分支,循环程序设计 ;3.掌握最简单的 DOS 功能调用.二.实验内容:1.安排一个数据区(数据段),内存有若干个正数,负数和零.每类数的个数都不超过 9.2.编写一个程序统计数据区中正数,负数和零的个数 .3.将统计结果在屏幕上显示.4.(选作)统计出正奇数,正偶数,负奇数,负偶数以及零的个数 .三.预习题:1.十进制数 0 - 9 所对应的 ASCII 码是什么? 如何将十进制数 0 - 9 在屏幕上显示出来?答:(1)十进制数 0-9 所对应
2、的 ASCII 码分别为:48、49、50 、 51、52、53、54、55、56、57,即30H、31H、32H 、33H 、34H、35H 、36H、37H、38H、39H。(2)将要显示的数字加上 30H,得到该数的 ASCII 码,再利用 DOS 功能调用显示单个字符。2.如何检验一个数为正,为负或为零 ? 你能举出多少种不同的方法 ?答:(1)采用 CMP 指令,观察标志位;(2)采用 TEST 指令,观察标志位;(3)将该数与 0 相与,观察标志位;(4)将该数与 0 相减,观察标志位。四流程图流程图 选作流程图五源代码(1)DATA SEGMENT ;数据段BUFF DW 5,-
3、3,-7,0,18,19,0,33 ;待检索的数字序列COUNT EQU $-BUFF ;此时,COUNT 的值为 BUFF 所占的字节数STRING DB 6 DUP(?) ;存放要显示的结果DATA ENDSCODE SEGMENT ;代码段ASSUME CS:CODE,DS:DATA,ES:DATA BEGIN:MOV AX,DATAMOV DS,AXMOV CX,COUNTSHR CX,1; 相当于除 2,正好为 BUFF 中的数据个数MOV DX,0 ; 设定计数器初值MOV AH,0 ; 设定计数器初值LEA BX,BUFFAGAIN: CMP WORD PTR BX,0JGE P
4、LU ;大于等于 0,则转 PIUINC AH ;0,则统计JMPNEXTZER: INC DH ;0 ,则统计NEXT: INC BXINC BX ;修改地址指针DEC CXJNZ AGAINmov al,dl ;DL 中存放整数的个数,移至 AL,准备显示CALL WORDPRINTmov ax, 4C00h ; terminate the program normallyint 21h;*;*显示结果*;*WORDPRINT PROC and al,0Fhcall hexdmov string,almov al,dh ;DH 中存放 0 的个数,移至 AL,准备显示and al,0Fhc
5、all hexdmov string+1, ;为增加可读性,在输出字符之间增加空格键mov string+2,almov al,ah ;AH 中存放负数个数,移至 AL,准备显示and al,0Fhcall hexdmov string+3, mov string+4,almov string+5,$ MOV AH,9MOV DX,OFFSET STRINGint 21hWORDPRINT ENDP;*;* 将 1 位十六进制数转换为其对应的 ASCII 码,其中入口参数为 AL 中存放的待*转换的十六进制数,出口参数为转换完的结果,存入 AL 中;*HEXD PROC NEAR CMP AL
6、,0AHJL ADDZADD AL,A-0-10ADDZ: ADD al,0RETHEXD ENDPCODE ENDSEND BEGIN(2)选作DATA SEGMENTBUFF DW 5,-3,-7,0,18,19,0,33,-4COUNT EQU $-BUFF ;;此时,COUNT 的值为 BUFF 所占的字节数TMP1 DB 0;负偶数个数TMP2 DB 0;负奇数个数STRING DB 10 DUP(?) ;存放待显示结果DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA ;初始化BEGIN:MOV AX,DATAMOV DS,AXM
7、OV CX,COUNTSHR CX,1; ;相当于除 2,正好为 BUFF 中的数据个数MOV DX,0 ; ;dh 中存放正奇数个数,dl 中存放正偶数个数MOV AH,0 ; ;ah 中存放 0 的个数LEA BX,BUFFAGAIN: CMP WORD PTR BX,0JGE PLU ;大于等于 0,则转 PIUJMPMINMIN: SHR WORD PTR BX,1 ;右移一位,相当于除以二JC MINJ ;若余数不为 0,则为负奇数INC TMP1 ;若余数为 0,则为负偶数,tmp1 加一JMP NEXT ;跳转到下一次循环MINJ: INC TMP2 ;若为负奇数, tmp2 加
8、一JMP NEXTPLU: JZ ZER ;;0,则转 ZERSHR WORD PTR BX,1JC PLUJINC DL ;0,则统计JMPNEXTPLUJ: INC DHJMP NEXTZER: INC aH ;0,则统计NEXT: INC BXINC BXDEC CXJNZ AGAINmov al,dHCALL WORDPRINT ;显示结果mov ax, 4C00h ; terminate the program normallyint 21h;*;*显示结果*;*WORDPRINT PROCand al,0Fhcall hexdmov string,almov al,dLand al
9、,0Fhcall hexdmov string+1, mov string+2,almov al,TMP2and al,0Fhcall hexdmov string+3, mov string+4,almov al,TMP1and al,0Fhcall hexdmov string+5, mov string+6,almov al,AHand al,0Fhcall hexdmov string+7, mov string+8,almov string+9,$MOV AH,9MOV DX,OFFSET STRINGint 21hWORDPRINT ENDP;*; *将 16 进制数转换为其对应的
10、 ASCII 码*;*HEXD PROC NEAR CMP AL,0AHJL ADDZADD AL,A-0-10ADDZ: ADD al,0RETHEXD ENDPCODE ENDSEND BEGIN六程序运行结果(1) 数据段中数字序列为:5,-3,-7,0,18,19,0,33,输出结果(正数、零、负数)分别为 4、2、2,结果正确;(2) 数据段中数字序列为:5,-3,-7,0,18,19,0,33,-4 ,输出结果(正奇数、正偶数、负奇数、负偶数、零)分别为 3、1、2、1、2,结果正确。七实验心得实验中用到了基本的分支、循环程序以及用来显示结果的 DOS 功能调用,这使我在实际操作中
11、对这些语法有了理论课上不曾思考过的收获。当然,在程序调试中,也遇到了一些问题,比如如何更方便地判断是奇数等,在经过比较和思考后,最终决定用右移一位看标志位的方式来做出判断。实验三 代码转换程序设计一.实验目的:1.掌握几种最基本的代码转换方法;2.运用子程序进行程序设计.二.实验内容:1.从键盘上输入若干两位十进制数,寻找其中的最小值 ,然后在屏幕上显示出来.2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明.3.对输入要有检错措施,以防止非法字符输入 ,并有适当的提示.4.将整个程序分解为若干模块,分别用子程序实现.在报告中要给出模块层次图.三.预习题:1.如何将输入的两个字符
12、(0 - 9)变为十进制或二进制数?答:将输入的字符减去 30H,即可得到其对应的二进制数,高位乘以 10,加上低位,即为这两个字符组成的十进制数。2.如何将选出的最小值(二进制或十进制)变为 ASCII 码再进行显示?答:将选出的最小值(此程序中为十进制数)通过 1.中的逆变换转换为十六进制数,即其 ASCII 码即可显示。3.你觉得采用二进制运算还是十进制运算更适合于这个实验?答:十进制。四模块层次图模块层次图五程序流程图程序流程图六源代码DATA SEGMENTSTRING DB 0DH,0AH,ERROR!,0DH,0AH,$ ;错误提示STRINGM DB The minimum n
13、umber is:,$;显示结果STRINGS DB 3 DUP(?) ;用来存放最小数SHIWEI DB ?;存放最小数十位GEWEI DB ?;存放最小数个位TMP DB ?;用来显示有没有更新十位EQUAL DB ?;用来指示高位是否相等DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATABEGIN:MOV AX,DATAMOV DS,AXMOV TMP,0 ;初始化MOV CX,0MOV EQUAL,0;MOV SHIWEI,57;MOV GEWEI,57;LOOP2:MOV AH,1 ;键盘输入一个数INT 21Hcmp al,48h
14、 ;判断是否输入合法字符(09 ) ,否则报错jl errorcmp al,57hjg errorCMP AL,0DH ;判断是否是回车键JZ SHOWCMP CX,0 ;判断当前是否输入高位JNZ LETTERSJMP LETTER0LETTER0:CMP AL,20H ;判断是否输入空格 ,如果是,则报错JZ ERRORCMP AL,SHIWEI ;比较当前输入高位与已有最小数高位,如果前者较小, 则更新,否则继续判断JLE UPDATESINC CX ;用来指示位数的变量更新JMP LOOP2UPDATES: ;更新高位CMP AL,SHIWEIJZ UPDATEEMOV SHIWEI,
15、ALMOV TMP,1 ;TMP 为一 ,表示高位已更新INC CXJMP LOOP2UPDATEE:MOV EQUAL,1;MOV SHIWEI,ALMOV TMP,1 ;TMP 为一 ,表示高位已更新INC CXJMP LOOP2UPDATEG:MOV GEWEI,ALINC CXJMP LOOP2LETTERS:CMP CX,2JZ LETTER2CMP AL,20H ;如果当前 CX 为 1,则输入低位,如果输入为空格则报错JZ ERRORCMP EQUAL,1JZ LOOP1CMP TMP,0 ;如果 TMP 为 0,表示高位未更新,否则要更新低位JNZ UPDATEGINC CXJ
16、MP LOOP2LOOP1:CMP AL,GEWEIJLE UPDATEGINC CXJMP LOOP2LETTER2:CMP AL,20H ;判断是否是空格 ,如果不是则报错,如果是,则更新 cx,并继续输入JNZ ERRORDEC CXDEC CXMOV EQUAL,0MOV TMP,0JMP LOOP2ERROR: ;报错模块,显示报错信息MOV AH,09HMOV DX,SEG STRINGMOV DS,DXMOV DX,OFFSET STRINGINT 21H RETSHOW:CMP CX,2 ;判断是否全部输入为两位数JNZ ERRORCALL WORDPRINT ;显示字符串及数
17、字mov ax, 4C00h ; terminate the program normallyint 21hWORDPRINT PROC ;显示结果子程序MOV AH,09HMOV DX,SEG STRINGMMOV DS,DXMOV DX,OFFSET STRINGMINT 21H MOV AL,shiWEIand al,0Fhcall hexdmov string,alMOV AL,geWEIand al,0Fhcall hexdmov string+1,alMOV STRING+2,$MOV AH,9MOV DX,OFFSET STRINGint 21hWORDPRINT ENDPHEX
18、D PROC NEAR ;将十六进制数转换成其对应的 ASCII 码CMP AL,0AHJL ADDZADD AL,A-0-10ADDZ: ADD al,0RETHEXD ENDPCODE ENDSEND BEGIN七程序运行结果由程序运行结果截图可知,经键盘输入多个两位十进制数,可将其中的最小值筛选出来并显示在屏幕上。该程序中,两个十进制数中间的分隔符为空格键,结束输入的标志是回车。同时在结果中也可以看出来,当输入不符合要求或输入非法字符时,程序会显示提示错误信息。八实验心得本实验主要用到了多进制之间的转换程序,输入十进制数,获得其对应的ASCII 码,然后将其还原为十进制数,并进行比较,最
19、后再将最小值转换成ASCII 码,通过特定的显示子程序显示在屏幕上。通过本次实验,我对用汇编语言实现各种进制之间的转换有了更多的了解,也有了更多的经验。当然,这个过程经历了很多次的调试,才实现了最终的效果。不过,调试程序的过程显得更加重要,因为它使我对原理理解得更加深入。比如,初次完成的程序并不能正确得出最小值,经过反复的调试,最终发现是因为对程序之间的跳转理解有偏差,导致部分语句重复执行,同时,也明确了JMP 语句与子程序跳转之间的联系和区别,前者不会再返回跳转之前的地方,后者则可以保存子程序跳转之前执行到的主程序的位置,在执行完子程序后可继续回到主程序执行下面的语句。实验四 子程序设计一.
20、实验目的:1.进一步掌握子程序设计方法;2.进一步掌握基本的 DOS 功能调用.二.实验内容:1.从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入. 2.统计检查每个学生的名次.3.将统计结果在屏幕上显示.4.为便于观察,输入学生数目不宜太多 ,以不超过一屏为宜.输出应便于阅读. 尽可能考虑美观.5.输入要有检错手段.三.预习题:1.如何确定一个学生在这门科目中的名次?答:可以通过遍历其他同学的成绩,统计其中比该生成绩高的同学的个数,即为该生在这门科目中的名次。2.你觉得输入结束后,采用什么方法进行比较以得到学生的名次最为简单?答:可以采用简单选择排序的方式,将所有同学的成
21、绩按从高到低的顺序排序,以得到学生的名次。3.准备好模块层次图.4.给出输出显示的形式.答: 学生人数 nStu Score RankStu_n Score_n 1Stu_m Score_m 2Stu_l Score_l 3.四程序流程图五源代码DATA SEGMENT ;数据段定义BUFFER DB 100DB 0DB 100 DUP(0)CNT1 DB 1CNT2 DB 1CNT3 DB 1STRING1 DB Stu Score Rank,0DH,0AH,$;最终显示的表项STRING2 DB ,$ ;用于规范格式,使最终显示的表项对齐STRING3 DB Please input th
22、e scores(100-:0),0DH,0AH,$;提示输入信息STRING4 DB ERROR!,0DH,0AH,$;报错提示信息RANK DB 100 DUP(?);名次SCORE DB 100 DUP(?);分数STU DB 100 DUP(?);学生DATA ENDSSTACK SEGMENT STACK STACK;堆栈段定义DB 100 DUP(?)STACK ENDSCODE SEGMENT ;代码段ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATASTART:MOV AX,DATAMOV DS,AXMOV AH,09H ;显示提示输入信息对应的字符
23、串MOV DX,SEG STRING3MOV DS,DXMOV DX,OFFSET STRING3INT 21HCALL INPUT ;调用输入各学生名次的子程序CALL CHANGEROW ;调用换行子程序CALL CHECK ;调用检错子程序CMP AL,0 ;判断是否输入合法字符,否则报错JZ ERRORCALL TRANSFER ;调用子程序,将 ASCII 码转为二进制数CMP AL,0JZ ERRORCALL RANKING ;调用子程序,进行名次排序CALL CHANGEROWCALL SHOW ;调用显示子程序MOV AX,4C00HINT 21HERROR:MOV DX,OF
24、FSET STRING4 ;报错提示MOV AH,09HINT 21HJMP START;*;*输入子程序*;*INPUT PROC MOV DX,SEG BUFFERMOV DS,DXMOV DX,OFFSET BUFFERMOV AH,0AH ;DOS 功能调用,键盘输入一串字符串INT 21HRET INPUT ENDP;*;*换行子程序*;*CHANGEROW PROC MOV AH,02HMOV DL,0DH ;回车换行INT 21HMOV AH,02HMOV DL,0AHINT 21HRETCHANGEROW ENDP;*;检错子程序,若输入为数字、空格、回车以外的字符则报错,且用
25、:0 来代替100;*CHECK PROC NEAR MOV BX,OFFSET BUFFERMOV CL,BUFFER+1 ;实际输入字符数MOV CH,0LOOP1:MOV AL,BX+2CMP AL,30H ;不是数字或:时判断是否是空格JB KONGGECMP AL,40HJA KONGGENEXT1:INC BX ;循环LOOP LOOP1RETKONGGE:CMP AL,20H ;判断是否是空格JZ NEXT1MOV AL,0RETCHECK ENDP;*;将 ASCII 码转换为二进制数;*TRANSFER PROC MOV BX,OFFSET BUFFERMOV DI,OFFS
26、ET SCOREMOV SI,OFFSET STUMOV CH,0NEXT2:MOV AL,BX+2CMP AL,20H;判断是否是空格JZ ENDFOUCMP AL,0DH;判断是否是回车JZ EXITSUB AL,30H;将 ASCII 码变为二进制ADD AL,ALMOV DH,ALMOV CL,2SHL AL,CLADD AL,DHMOV AH,BX+3SUB AH,30HADD AL,AHMOV DI,AL ;将得到的二进制数保存到 SCORE 中INC CHMOV SI,CH ;添加到 STU 中ADD BX,2MOV AL,BX+2 ;判断是否有空格CMP AL,20HJNZ E
27、NDFOUINC BXINC DIINC SIJMP NEXT2 ;循环RETENDFOU:CMP AL,0DH ;若遇回车,则输入结束JZ EXITMOV AL,0EXIT:RETTRANSFER ENDP;*;排序子程序;*RANKING PROC MOV AL,CH ;显示学生人数ADD AL,30HMOV AH,02HMOV DL,ALINT 21HLEA SI,SCORE ;简单选择排序LEA DI,SCORELEA BP,STULEA BX,SCORE+1SUB BP,SINEXT3:MOV AL,CNT2MOV CNT1,ALNEXT4:MOV AL,SI ;SI 指向最大数,初
28、始化为第一个数,不断更新MOV AH,BXCMP AH,ALJBE NEXT5 ;小于等于进行跳转,不改变 SI,继续比较MOV SI,BX ;大于时更新INC BXINC CNT1;用于计数,判断是否比较结束CMP CNT1,CHJZ CHANGE ;每轮选择结束后将乱序区最大值与区内第一个数交换位置JNZ NEXT4NEXT5:INC BXINC CNT1CMP CNT1,CHJZ CHANGEJMP NEXT4CHANGE:MOV AL,SI;SI 指向乱序区最大值,DI 指向区内第一个数MOV AH,DIMOV DI,ALMOV SI,AHMOV AL,DS:BP+SI ;交换学生信息
29、MOV AH,DS:BP+DIMOV DS:BP+DI,ALMOV DS:BP+SI,AHINC DI ;乱序区大小更新INC CNT2;计数,比较 N-1 轮CMP CNT2,CHJZ EXIT1MOV SI,DI ;初始化下一轮比较的起始位置MOV BX,DIINC BXJMP NEXT3;循环,进行下一次比较EXIT1:RETRANKING ENDP;*;显示结果子程序;*SHOW PROC LEA SI,STULEA DI,SCOREMOV AH,09H ;显示列名MOV DX,SEG STRING1MOV DS,DXMOV DX,OFFSET STRING1INT 21HNEXT6:
30、MOV AL,SI;显示学生信息ADD AL,30HMOV AH,02HMOV DL,ALINT 21HCALL ADJUST ;显示分数MOV AL,DICBWMOV BL,10DIV BLMOV BH,AH;显示十位ADD AL,30HMOV AH,02HMOV DL,ALINT 21HMOV AL,BH;显示个位ADD AL,30HMOV AH,02HMOV DL,ALINT 21HINC SIINC DICALL ADJUSTMOV AH,02HMOV AL,CNT3ADD AL,30HMOV DL,ALINT 21HINC CNT3CALL CHANGEROWDEC CHJNE NE
31、XT6JMP EXIT2ADJUST:MOV AH,09H;利用空格来规范格式MOV DX,SEG STRING2MOV DS,DXMOV DX,OFFSET STRING2INT 21HRETEXIT2:NOPRETSHOW ENDPCODE ENDSEND START六程序运行结果由程序运行结果可知,该程序可以实现按学号由键盘输入各学生的成绩,自动排序,并将最终的排名结果显示在屏幕上。不足之处是“100”的输入和显示尚待改进。七实验心得本实验中主要练习了子程序的设计与 DOS 功能调用,使我对程序的框架设计和模块划分有了更深的认识。当然,程序仍然是通过不断的调试才实现以上功能的。比如,一开
32、始没有加格式规范模块(用特定个数的空格键使格式整齐)和换行模块,导致程序输出混乱,可读性差,在不断摸索之后才确定添加上述两个模块,从而基本符合美观性要求。这些经历更能使我受益匪浅。实验五 中断程序设计一.实验目的:1.初步掌握中断程序的设计方法:2.初步掌握修改 DOS 系统中断,以适应实际使用的方法.二.实验内容:1.编写一个 32 位二进制数除以 16 位二进制数的除法程序.观察当除数为 0,或超过相应寄存器范围时,程序执行的结果.2.修改零号中断服务程序,使它具有以下功能:(1)判断除数是否为 0,当除数为 0 时,显示相应的结果;(2)当除数不为 0 时,采用适当的方法完成商超过 16
33、 位的二进制数的除法运算.3.注意必须保护原有中断服务程序的入口地址,并在程序完毕前加以恢复.4.(选作) (1)用二进制将结果在屏幕上显示.(2)从键盘输入二进制数.三.预习题:1.如何保护原有中断向量表中的中断服务程序的入口地址?答:将原有中断向量表中的中断服务程序的入口地址压入堆栈进行保护。2.如何将你的中断服务程序入口地址置入中断向量表?DOS 功能调用 25H 用来写中断向量表,入口参数如下:AL:中断类型号;DS:中断服务子程序入口的段地址;DX:中断服务子程序入口的偏移地址。四.流程图总体流程图 中断服务子程序流程图五源代码DATA SEGMENTMESSAGE DBDivide
34、 overflow.Divisor equals 0.,0DH,0AH,$STRING1 DB Please input the dividend(32bit):,0DH,0AH,$STRING2 DBPlease input the divisor(16bit):,0DH,0AH,$STRING3 DBIllegal input,please input again.,0DH,0AH,$DIVIDEND DD ? ;存储 32 位被除数DIVISOR DW ? ;存储 16 位除数RESULT DB 0DH,0AH,The consult is:,0AH,0DHCONSULT DB 30HD
35、B 31 DUP( )DB 0DH,0AH,The remainder is:,0DH,0AHREMAINDER DB 30HDB 15 DUP( )DB $DATA ENDSSTACK SEGMENT STACK STACKDB 50 DUP(0)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART PROC FARPUSH DSMOV AX,0PUSH AXMOV AX,DATAMOV DS,AXMOV DX,OFFSET STRING1;被除数输入提示MOV AH,09HINT 21HCALL INPUT1;调用输入被除数子
36、程序,接收输入被除数并存入内存MOV DX,OFFSET STRING2;除数输入提示MOV AH,09HINT 21HCALL INPUT2;调用输入除数子程序,接收输入除数并存入内存STI;开中断MOV AL,0;保存原中断向量MOV AH,35HINT 21HPUSH ESPUSH BXPUSH DS;写中断向量表MOV AX,SEG INT00MOV DS,AXMOV DX,OFFSET INT00MOV AL,0MOV AH,25HINT 21HPOP DSMOV CX,0;做除法,若商大于 16 位则保存在 CX:AX 中,余数在 DXLEA SI,DIVIDENDMOV AX,W
37、ORD PTRSIMOV DX,WORD PTRSI+2LEA SI,DIVISORMOV BX,WORD PTRSIDIV BXCMP BX,0 ;若除数为 0 则退出JZ EXITCALL OUTPUT ;调用输出子程序,将二进制数转换为 ASCII 码并存入内存MOV DX,OFFSET RESULT;输出二进制结果MOV AX,0MOV AH,09HINT 21HPOP DX ;恢复中断向量表POP CXPUSH DSMOV DS,CXMOV AL,0MOV AH,25HINT 21HPOP DSEXIT:MOV AX,4C00HINT 21H;*;*修改后的除法溢出中断服务子程序(1
38、6 位除数) *;*功能:除数为 0,给出错误信息;除数不为 0,计算结果*;*INT00 PROC FARPOP CX ;修改返回地址ADD CX,2PUSH CXCMP BX,0JNE NEXTLEA DX,MESSAGE ;除数为 0,显示错误信息MOV AH,09INT 21HJMP FINISHNEXT:;PUSH AX;将被除数低 16 位先保存起来MOV AX,DX;将高 16 位挪到低 16 位MOV DX,0;将高 16 位清零DIV BXMOV CX,AX;得到商的高 16 位POP AXDIV BX;此时 32 位商保存在 CX:AX 中,余数保存在 DX 中FINISH
39、:IRETINT00 ENDP;*;输入被除数子程序;*INPUT1 PROC PUSH AX;压入堆栈,保护数据PUSH BXPUSH CXPUSH DXPUSH SIBEGIN:MOV AX,0;MOV BX,0FFFFHPUSH BXMOV BX,0MOV CX,0LOOP1:MOV AH,01INT 21HCMP AL,1 ;检查输入是否错误JA ERROR_INPUTCMP AL,0JB ERROR_INPUTSUB AL,30H ;数制转换MOV DX,0SHL BX,1JNC ZFZ1;检查进位MOV DX,1ZFZ1:PUSH DXCMP CX,0JNZ CXEQZ;如果高 1
40、6 位不为零则需要移位POP DXADD CX,DXADD BL,ALJMP LOOP1CXEQZ:SHL CX,1;若有进位则报错JC ERROR_INPUTPOP DX;弹出低 16 位的进位ADD CX,DX;高 16 位加低 16 位的进位ADD BL,ALJMP LOOP1ENDINPUT:LEA SI,DIVIDENDMOV SI,BXMOV SI+2,CXPOP BXPOP SI;恢复现场POP DXPOP CXPOP BXPOP AXRETERROR_INPUT:CMP AL,0DH;检查是否输入结束JZ ENDINPUTLOOP3:POP BX;输入错误,将原来压入堆栈的数据
41、弹出,并要求重新输入CMP BX,0FFFFHJNZ LOOP3MOV DX,OFFSET STRING3MOV AH,09HINT 21HJMP BEGININPUT1 ENDP;*;输入除数子程序;*INPUT2 PROC PUSH AXPUSH BXPUSH DXPUSH SIBEGIN2:MOV AX,0MOV BX,0LOOP2:MOV AH,01INT 21HCMP AL,1JA ERROR_INPUT2CMP AL,0JB ERROR_INPUT2SUB AL,30H;数制转换SHL BX,1;将 BX 中的数左移一位,若不溢出则与新输入的数相加JC ERROR_INPUT2;若
42、有进位则报错ADD BL,ALJMP LOOP2ENDINPUT2:MOV SI,OFFSET DIVISORMOV SI,BXPOP SI;恢复现场POP DXPOP BXPOP AXRETERROR_INPUT2:CMP AL,0DHJZ ENDINPUT2MOV DX,OFFSET STRING3MOV AH,09HINT 21HJMP BEGIN2INPUT2 ENDP;*;输出子程序,用二进制输出商和余数;*OUTPUT PROC PUSH BXPUSH SIPUSH DIMOV BX,0FFFFHPUSH BXMOV DI,16TRAFORM:CMP AX,0;当 ax=0 时,如
43、果高 16 位为零则停止提取,否则须将低 16位的每一位都提取出来JZ END1MOV BX,0DEC DISHR AX,1JNC NEXT1MOV BX,1NEXT1:ADD BX,30HPUSH BXJMP TRAFORMEND1:CMP CX,0JZ OUTDI1CMP DI,0JA TRAFORM ;未提取完,继续提取MOV AX,CXMOV CX,0JMP TRAFORMOUTDI1:LEA SI,CONSULT;将二进制数字对应的 ASCII 码输出到内存LOP1:POP BXCMP BX,0FFFFHJZ NEXTDIVMOV SI,BLINC SIJMP LOP1NEXTDIV
44、:MOV BX,0FFFFH;余数转换PUSH BXMOV BX,0TRAFORM1:CMP DX,0JZ END2MOV BX,0SHR DX,1JNC NEXT2MOV BX,1NEXT2:ADD BX,30HPUSH BXJMP TRAFORM1END2:LEA SI,REMAINDERLOP2:POP BXCMP BX,0FFFFHJZ ENDDMOV SI,BLINC SIJMP LOP2ENDD:POP DIPOP SIPOP BXRETOUTPUT ENDPCODE ENDSEND START六程序运行结果由程序运行结果截图可知,该程序实现了对输入字符的检错、除数为零时的报错、除法溢出时的正确处理等功能,并且有适当的交互语句,可执行性高。七实验心得本实验主要考察对微机原理与接口技术第八章中断系统相关知识的掌握情况,需要熟练地掌握 DOS 功能调用,熟知中断服务子程序的运行原理和调用情况。本实验要注意的重点有:一定要“保护现场” “恢复现场” ,以在执行完中断子程序后正确返回原中断处继续执行主程序的语句;可采取将高 16 位和低16 位被除数分开来做除法的方式。通过本次实