北邮微原软件实验报告.docx
《北邮微原软件实验报告.docx》由会员分享,可在线阅读,更多相关《北邮微原软件实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
北邮微原软件实验报告
北京邮电大学
2017微原软件
实验报告
实验二分支,循环程序设计
一.实验目的:
1.开始独立进行汇编语言程序设计;
2.掌握基本分支,循环程序设计;
3.掌握最简单的DOS功能调用.
二.实验内容:
1.安排一个数据区(数据段),内存有若干个正数,负数和零.每类数的个数都不超过9.
2.编写一个程序统计数据区中正数,负数和零的个数.
3.将统计结果在屏幕上显示.
三.程序流程图及源代码
DATASEGMENT
BUFFDW-75,0,23,123,0,12,-99,-78,0,24,47,25,-77,28,62
COUNTEQU$-BUFF;BUFF所占的字节数
STRING1DB'Thenumberofplusis',20H
PLUSDB?
;大于零的数的个数
STRING2DB0DH,0AH,'$'
STRING3DB'Thenumberofzerois',20H
ZERODB?
;等于零的数的个数
STRING4DB0DH,0AH,'$'
STRING5DB'Thenumberofminusis',20H
MINUSDB?
;小于零的数的个数
STRING6DB0DH,0AH,'$'
DATAENDS
STACKSEGMENTSTACK'STACK'
DB100DUP(0)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,ES:
DATA,SS:
STACK
BEGIN:
MOVAX,DATA
MOVDS,AX
MOVCX,COUNT
SHRCX,1;相当于除2,为BUFF中数据的个数
MOVDX,0;设定初值;DH,DL分别为等于零,大于零的个数
MOVAH,0;设定初值;AH为小于零的个数
LEABX,BUFF
AGAIN:
CMPWORDPTR[BX],0
JGEPLU;大于等于零时转到PLU
INCAH;统计小于零的个数
JMPNEXT
PLU:
JZZER;等于零时转ZER
INCDL;统计大于零的个数
JMPNEXT
ZER:
INCDH;统计小于零的个数
NEXT:
INCBX;修改地址指针
INCBX
LOOPAGAIN
MOVMINUS,AH;保存结果
ADDMINUS,30H
MOVPLUS,DL
ADDPLUS,30H
MOVZERO,DH
ADDZERO,30H
MOVAH,09H
MOVDX,SEGSTRING1
MOVDS,DX
MOVDX,OFFSETSTRING1
INT21H
MOVAH,09H
MOVDX,SEGSTRING3
MOVDS,DX
MOVDX,OFFSETSTRING3
INT21H
MOVAH,09H
MOVDX,SEGSTRING5
MOVDS,DX
MOVDX,OFFSETSTRING5
INT21H
MOVAX,4C00H
INT21H
CODEENDS
ENDBEGIN
四.程序运行结果
五.选作题:
统计出正奇数,正偶数,负奇数,负偶数以及零的个数.
六.选做题的源代码
DISPLAYMACROY;显示字符串
MOVAH,09H
MOVDX,SEGSTRING&Y
MOVDS,DX
MOVDX,OFFSETSTRING&Y
INT21H
ENDM
DATASEGMENT
BUFFDW-624,0,34,89,-45,0,-45,324,0,12,-99,-65,33,1,37,0,-
88,35,-7,0,11
COUNTEQU$-BUFF;BUFF所占的字节数
STRINGADB'Thenumberofpositiveoddnumberis',20H
PODDDB?
;正奇数的个数
STRING1DB0DH,0AH,'$'
STRINGBDB'Thenumberofnegativeoddnumberis',20H
NODDDB?
;负奇数的个数
STRING2DB0DH,0AH,'$'
STRINGCDB'Thenumberofzerois',20H
ZERODB?
;零的个数
STRING3DB0DH,0AH,'$'
STRINGDDB'Thenumberofpositiveevennumberis',20H
PEVENDB?
;正偶数的个数
STRING4DB0DH,0AH,'$'
STRINGEDB'Thenumberofnegativeevennumberis',20H
NEVENDB?
;负偶数的个数
STRING5DB0DH,0AH,'$'
DATAENDS
STACKSEGMENTSTACK'STACK'
DB100DUP(0)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,ES:
DATA,SS:
STACK
BEGIN:
MOVAX,DATA
MOVDS,AX
MOVCX,COUNT
SHRCX,1;相当于除2,为BUFF中的数据个数
LEAAX,BUFF
MOVSI,AX
MOVDX,0;设定初值:
DL,DH,AL,AH,BH中分别为正偶数,正奇数,负偶数,负奇数,零的个数
MOVAX,0
MOVBX,0
AGAIN:
CMPWORDPTR[SI],0
JGEPLU;大于等于零转到PLU
JMPMINUS;否则转到MINUS
PLU:
JZZER;等于零转到JZ
TESTWORDPTR[SI],01H
JNZPO;最低位为1转到PO
INCDL;统计正偶数的个数
JMPNEXT
MINUS:
TESTWORDPTR[SI],01H
JNZNO;最低位为1转到NO
INCAL;统计负偶数的个数
JMPNEXT
PO:
INCDH;统计正奇数的个数
JMPNEXT
NO:
INCAH;统计负奇数的个数
JMPNEXT
ZER:
INCBH;统计零的个数
NEXT:
INCSI;修改地址指针
INCSI
LOOPAGAIN
MOVZERO,BH;结果的储存与显示
ADDZERO,30H
MOVPEVEN,DL
ADDPEVEN,30H
MOVPODD,DH
ADDPODD,30H
MOVNEVEN,AL
ADDNEVEN,30H
MOVNODD,AH
ADDNODD,30H
DISPLAYA
DISPLAYB
DISPLAYC
DISPLAYD
DISPLAYE
MOVAX,4C00H
INT21
CODEENDS
ENDBEGIN
七.选做题的运行结果
实验三代码转换程序设计
一.实验目的:
1.掌握几种最基本的代码转换方法;
2.运用子程序进行程序设计.
二.实验内容:
1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来.
2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明.
3.对输入要有检错措施,以防止非法字符输入,并有适当的提示.
4.将整个程序分解为若干模块,分别用子程序实现.在报告中要给出模块层次图.
三.流程图
四.源代码
DATASEGMENT
MINDB'9','9'
STRING0DB0DH,0AH,'PLEASEINPUTSOMEINTEGER(2NUMBERS)WITHSPACEANDSTOPWITHENTER:
',0DH,0AH,'$'
STRING1DB0DH,0AH,'ERROR!
PLEASEINPUTAGAIN:
',0DH,0AH,'$'
STRING2DB0DH,0AH,'MINIS:
',0DH,0AH,'$'
DATAENDS
STACKSEGMENTSTACK'STACK'
DB100DUP(?
)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,ES:
DATA,SS:
STACK
;***********输入子函数***********
INPUTPROCNEAR;键盘输入的子程序,AL=输入码
MOVAH,01H;键盘输入的功能码
INT21H
RET;回到DOS
INPUTENDP
;***********检查子函数***********
TESTEPROCNEAR;检查输入字符是否符合要求
CMPAL,'0'
JBERROR
CMPAL,'9'
JAERROR;若输入字符的ASCII码不在0-9范围内判为输入错误
JMPEXIT;否则转EXIT
ERROR:
MOVAL,0H
ERROR1:
MOVDX,OFFSETSTRING1;输出错误提示
MOVAH,09H
INT21H
JMPCYCLE;回到主循环
EXIT:
RET
TESTEENDP;退出检测
;**********比较子函数**********
COMPPROCNEAR
CMPBX,WORDPTRMIN;比较BX的内容和MIN指向的数据段内存的数据
JBCHANGE;如果BX小于现有的最小值,转CHANGE
JMPCYCLE;否则回到主循环
CHANGE:
MOVWORDPTRMIN,BX
JMPCYCLE
RET
COMPENDP
;**********显示子函数**********
SHOWPPROCNEAR
CMPBX,WORDPTRMIN
JBUPDATE
DISPLAY:
MOVDX,OFFSETSTRING2
MOVAH,09H
INT21H
MOVDL,MIN+1
MOVAH,02H
INT21H
MOVDL,MIN
MOVAH,02H
INT21H
MOVDL,0DH
INT21H
MOVDL,0AH
INT21H
MOVAH,4CH;返回DOS
INT21H
UPDATE:
MOVWORDPTRMIN,BX
JMPDISPLAY
RET
SHOWPENDP
;************主程序开始**********
MAIN:
MOVAX,DATA
MOVDS,AX;给当前的数据段基地址赋值
MOVDX,OFFSETSTRING0;将STRING0的偏移地址赋值给DX
MOVAH,09H;字符串打印输出
INT21H
CYCLE:
;循环
CALLINPUT;调用键盘输入的子程序输入十位
CALLTESTE;调用检测的子程序
CMPAL,00H
JZERROR1
MOVBH,AL;将十位存入BH,待后面比较大小
CALLINPUT;调用键盘输入的子程序输入个位
CALLTESTE;调用检测的子程序
CMPAL,00H
JZERROR1
MOVBL,AL;将个位存入BL,待后面比较大小
CALLINPUT
CMPAL,0DH;判断此时是否输入了ENTER键结束
JZSHOW;是则转SHOW
CMPAL,'';判断是否输入空格键分割两个数
JZCOMPARE;是则转COMPARE比较更新最小数
JMPERROR1;都不是则是输入错误
COMPARE:
CALLCOMP
SHOW:
CALLSHOWP
CODEENDS
ENDMAIN
五.运行结果
实验四子程序设计
一.实验目的:
1.进一步掌握子程序设计方法;
2.进一步掌握基本的DOS功能调用.
二.实验内容:
1.从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入.
2.统计检查每个学生的名次.
3.将统计结果在屏幕上显示.
4.为便于观察,输入学生数目不宜太多,以不超过一屏为宜.输出应便于阅读.尽可能考虑美观
5.输入要有检错手段.
三.流程图
四.源代码
DATASEGMENT
BUFF0DW10DUP(0000H);存放成绩(一个字节存放一位十进制数的ASCII码值)
BUFF1DB10DUP(31H,32H,33H,34H,35H,36H,37H,38H,39H,40H);存放序号
BUFF2DB10DUP(31H,32H,33H,34H,35H,36H,37H,38H,39H,40H);存放排名
COUNT1DB0;BUFF中存放的字节数/内层冒泡需比较的次数
COUNT2DB0;BUFF中存放的成绩个数
STRING0DB0DH,0AH,'PLEASEINPUTTHESCORES:
',0DH,0AH,'$';输入成绩提示
STRING1DB0DH,0AH,'ERROR!
PLEASEINPUTAGAIN:
',0DH,0AH,'$';输入错误提示
STRING2DB0DH,0AH,'RANK:
','$';排名输出
STRING3DB0DH,0AH,'NUMBER:
','$';序号输出
STRING4DB0DH,0AH,'SCORES:
','$';成绩输出
DATAENDS
STACKSEGMENTSTACK'STACK'
DB100DUP(?
)
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,SS:
STACK
;**********输入子函数*********
INPUTPROC
MOVAH,01H
INT21H;AL=输入字符
RET
INPUTENDP
;**********输入检错子函数*********
TEST1PROC
CMPAL,'0'
JBERROR
CMPAL,'9'
JAERROR;输入字符不是0到9之间的数转ERROR
JMPEXIT
ERROR:
MOVAL,00H
EXIT:
RET
TEST1ENDP
;**********存储子函数**********
SAVE1PROC;十位存在高地址
MOVSI,OFFSETBUFF0;将成绩变量的偏移量首地址赋给SI
MOVCX,0000H
MOVCL,COUNT1;做SI的偏移量
ADDSI,CX
INCSI;先存储十位,十位存在高地址
MOV[SI],AL;将AL中的输入数据存在地址为SI的内存中
INCCOUNT1;成绩变量的字节数加一
RET
SAVE1ENDP
SAVE2PROC;再存储个位,个位存入低地址
MOVSI,OFFSETBUFF0
MOVCX,0000H
MOVCL,COUNT1
ADDSI,CX
DECSI;个位存在低地址
MOV[SI],AL
INCCOUNT1;成绩变量的字节数加一
RET
SAVE2ENDP
;***********两两比较并排序子函数**********
COMPAREPROC;两两比较,并将大数存在低地址
CMPAX,BX;AX是低地址的,BX是高地址的
JBEXCHANGE
JMPEXIT0
EXCHANGE:
;交换成绩
MOVCX,0
MOVSI,OFFSETBUFF0
ADDSI,DX;DX是当前偏移的字节个数
MOV[SI],BX
ADDSI,2
MOV[SI],AX
;交换序号
MOVSI,OFFSETBUFF1
SHRDX,1;BUFF1是BYTE
ADDSI,DX
MOVAH,[SI];序号交换
INCSI
MOVBH,[SI]
MOV[SI],AH
DECSI
MOV[SI],BH
EXIT0:
RET
COMPAREENDP
;***********主程序入口**********
START:
MOVAX,DATA
MOVDS,AX
MOVDX,OFFSETSTRING0
MOVAH,09H
INT21H
MOVAX,0000H
CYCLE:
CALLINPUT
CALLTEST1
CMPAL,00H
JZWRONG0
CALLSAVE1;保存十位数
CALLINPUT
CALLTEST1
CMPAL,00H
JZWRONG0
CALLSAVE2;保存个位数
CALLINPUT
CMPAL,0DH
JZLIST;输入回车,转LIST,排序
CMPAL,''
JZCYCLE;输入空格,继续处理下一个数
JMPWRONG0;其他情况转WRONG0
WRONG0:
MOVDX,OFFSETSTRING1
MOVAH,09H
INT21H
MOVCL,0;出现错误,计数复位
MOVCOUNT1,CL
JMPCYCLE
LIST:
MOVCL,COUNT1
SHRCL,1
MOVCOUNT2,CL;COUNT2中是待排序的数的个数
DECCL
MOVCOUNT1,CL;COUNT1中是每次外循环内循环需比较的次数及外循环的总次数
JZSHOW0
;**************冒泡排序**************
ORDER0:
MOVCL,0;内层循环计数器清零
ORDER1:
MOVSI,OFFSETBUFF0;内循环
MOVDH,0
MOVDL,CL;CL是内层循环计数器
SHLDL,1
ADDSI,DX
MOVAX,[SI];将此时BUFF中地址次低的数取出来放入AX中待比较
ADDSI,2
MOVBX,[SI];将此时BUFF中地址最低的数取出来放入BX中待比较
CALLCOMPARE;比较AX和BX,结果是将较大的数放入低地址存储
INCCL;内循环计数器CL加一
CMPCL,COUNT1
JEORDER2;当循环次数够了时需要进入外循环
JMPORDER1
ORDER2:
MOVCL,COUNT1;外循环
DECCL
MOVCOUNT1,CL;每执行完一次内循环内循环的循环次数COUNT1减一
JNZORDER0;只要计算得到的内循环次数不为零则开始下次内循环
JMPSHOW0
;**************打印名次************
SHOW0:
MOVDX,OFFSETSTRING2
MOVAH,09H
INT21H
MOVAH,02H
MOVSI,OFFSETBUFF2
MOVCL,COUNT2
SHOW00:
MOVDL,[SI]
INT21H
INCSI
MOVDL,''
INT21H
MOVDL,''
INT21H
DECCL
JNZSHOW00
;**************打印序号************
SHOW1:
MOVDX,OFFSETSTRING3
MOVAH,09H
INT21H
MOVAH,02H
MOVSI,OFFSETBUFF1
MOVCL,COUNT2
SHOW10:
MOVDL,[SI]
INT21H
INCSI
MOVDL,''
INT21H
MOVDL,''
INT21H
DECCL
JNZSHOW10
;**************打印成绩***************
SHOW2:
MOVDX,OFFSETSTRING4
MOVAH,09H
INT21H
MOVAH,02H
MOVSI,OFFSETBUFF0
MOVCL,COUNT2
SHOW20:
INCSI;先打印十位数中的(用ASCII码表示的)高位
MOVDL,[SI]
INT21H
DECSI;再打印十位数中的(用ASCII码表示的)低位
MOVDL,[SI]
INT21H
INCSI
INCSI
MOVDL,''
INT21H
DECCL
JNZSHOW20
;*************************************
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
五.程序执行结果