当前位置:文档之家› 微机原理与接口技术 北邮 软件 实验报告

微机原理与接口技术 北邮 软件 实验报告

微机原理与接口技术软件实验报告实验B 分支、循环程序设计一、实验目的1.开始独立进行汇编语言程序设计;2.掌握基本分支,循环程序设计;3.掌握最简单的DOS功能调用。

二、实验任务及内容1.安排一个数据区,内存有若干个正数,负数和零。

每类数的个数都不超过9。

2.编写一个程序统计数据区中正数,负数和零的个数。

3.将统计结果在屏幕上显示。

4. 选作题:统计出正奇数,正偶数,负奇数,负偶数以及零的个数.四、源程序DISPSTR MACRO STR ;打出字符串(属于DOS功能调用)MOV AH,9MOV DX,SEG STRMOV DS,DXMOV DX,OFFSET STRINT 21HENDMDISPNUM MACRO NUM ;打出数字(属于DOS功能调用)MOV AH,2MOV DL,NUMADD DL,30H ;加30H变为ASCII码INT 21HENDMDATA SEGMENTNUM DB 3,2,7,0,1,0,-5,-4,0COUNT EQU $-NUM ;统计数据个数ZEROS DB 0 ;各类数初值均为0PLUSES DB 0MINUSES DB 0EVENMINUSES DB 0ODDMINUSES DB 0EVENPLUSES DB 0ODDPLUSES DB 0ZEROSTR DB 0DH,0AH,'ZERO:$' ;待输出字符串PLUSSTR DB 0DH,0AH,'PLUS:$'MINUSSTR DB 0DH,0AH,'MINUS:$'EVENMINUSSTR DB 0DH,0AH,'EVENMINUS:$'ODDMINUSSTR DB 0DH,0AH,'ODDMINUS:$'EVENPLUSSTR DB 0DH,0AH,'EVENPLUS:$'ODDPLUSSTR DB 0DH,0AH,'ODDPLUS:$'DATA ENDSSTACK SEGMENT STACK 'STACK'DB 100 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE, DS:DATA, SS:STACKSTART PROC FARPUSH DS ;初始化MOV AX,0PUSH AXMOV AX,DATAMOV DS,AXMOV CX,COUNT ;CX控制循环次数MOV SI,OFFSET NUM ;SI指向数据的偏移地址LOOP1: CMP BYTE PTR[SI],0 ;将SI指向的内容与0比较大小JZ ZERO ;等于0跳转JG PLUS ;大于0跳转INC MINUSES ;负数加一SHR BYTE PTR[SI],1 ;判断是负奇数还是负偶数JNC EVENMINUS ;是负偶数跳转INC SI ;SI指针后移INC ODDMINUSES ;负奇数加一RETURN: LOOP LOOP1 ;循环直至CX=0JMP DISP ;循环结束后跳转至打出结果ZERO: INC ZEROSINC SIJMP RETURN ;返回循环体PLUS: INC PLUSESSHR BYTE PTR[SI],1JNC EVENPLUSINC SIINC ODDPLUSESJMP RETURNEVENPLUS: INC SIINC EVENPLUSESJMP RETURNEVENMINUS: INC SIINC EVENMINUSESJMP RETURNDISP: DISPSTR ZEROSTR ;打出结果DISPNUM ZEROSDISPSTR PLUSSTRDISPNUM PLUSESDISPSTR MINUSSTRDISPNUM MINUSESDISPSTR EVENPLUSSTRDISPNUM EVENPLUSESDISPSTR ODDPLUSSTRDISPNUM ODDPLUSESDISPSTR EVENMINUSSTRDISPNUM EVENMINUSESDISPSTR ODDMINUSSTRDISPNUM ODDMINUSESRETSTART ENDPCODE ENDSEND STARTend start五、程序运行结果进行统计的数据为3,2,7,0,1,0,-5,-4,0。

程序运行结果如下:六、回答预习题1.十进制数0 --9所对应的ASCII码是什么?如何将十进制数0--9在屏幕上显示出来?0--9的ASCII码为30H—39H。

若想将一个十进制数0—9的字符在屏幕上显示出来,首先应该把它所占寄存器的值赋给DL寄存器,然后DL寄存器的值加30H,然后执行02号DOS 功能调用,即执行以下代码“MOV AH,02”,“INT 21H”即可。

2.如何检验一个数为正,为负或为零?你能举出多少种不同的方法?1)可以用CMP指令将数与0比较,若为正数则可通过JG跳转;若为0可通过JE/JZ跳转;若为负数可通过JL跳转。

2)若只需判断是非负数或者负数,则可以用TEST指令将数与80H(DB情况下)或8000H(DW情况下)相与,若为非负数则可通过JE/JZ跳转;若为负数则可通过JNE/JNZ 跳转。

3)若只需判断是非负数或者负数,则也可以用SHL,SAL对数字进行左移,若为非负数可根据JNC判断;若为负数可以根据JC判断跳转。

4)若只需判断是非负数或者负数,则也可以用JS,JNS来进行判断,若为非负数可根据JNS跳转;若为负数可以根据JS判断跳转。

七、实验总结、建议要求、心得体会通过本次实验,我对宏定义和调用以及DOS功能调用有了更深的认识和学习。

同时,针对比较复杂的逻辑,需要将分支以及循环结构合理使用。

在对不同情况加以考虑时,要注意对不同判决条件的选择,不同的代码指令可能可以实现相同的功能。

实验的另一个收获是了解到了0—9字符ASCII码到实际数值的转化,为今后实验奠定了基础。

对于数字奇偶性的判断,可以采取不同的方法。

比如说可以使用TEST 语句实现对非0位的置0,而保留第0位来判断数字的奇偶性;或者使用SHR来对CF进行判断,也就是第0位。

使用不同的指令代码可以实现相同功能。

同时,考虑到输出的美观性,在汇编过程中,针对字符串,我有针对性的加入了0DH,0AH使得完成字符串输出的换行。

其中0AH是换行功能的ASCII码,0DH是回车功能的ASCII 码。

也是在本次实验中,我深刻认识到了宏定义与使用的重要性。

无论是输出字符还是字符串,这两个在实验中非常重要的功能完全可以通过简单的宏定义在汇编程序中多次调用。

使得汇编程序的可读性大大提高。

实验C 代码转换程序设计一、实验目的1.掌握几种最基本的代码转换方法;2.运用子程序进行程序设计。

二、实验任务及内容1.从键盘上输入若干两位十进制数,寻找其中的最小值,然后在屏幕上显示出来。

2.两个十进制数之间的分隔符,输入结束标志自定,但要在报告中说明。

3.对输入要有检错措施,以防止非法字符输入,并有适当的提示。

4.将整个程序分解为若干模块,分别用子程序实现。

在报告中要给出模块层次图。

三、程序流程图四、源程序(空格为两十进制数间的分隔符,空格为输入结束标志)DISPSTR MACRO STR (DOS功能调用)MOV AH,9MOV DX,SEG STRMOV DS,DXMOV DX,OFFSET STRINT 21HENDMDISPCH MACRO NUMMOV AH,2MOV DL,NUMINT 21HENDMDATA SEGMENTINSTR DB 31 ;最多能输入连回车在内的31个字符DB 0 ; 每输入一个两位数占3 byteDB 31 DUP(0)NUMS DB 10 DUP(0FFH) ;储存由字符串转化过来的实际数值COUNT DB ? ;记录实际数据的个数MIN DB 0FFH ;记录最小值,初始化为0FFHSTRIN DB 'PLEASE INPUT YOUR NUMBER:$'STRERR DB 0DH,0AH,'WRONG INPUT!',0DH,0AH,'PLEASE INPUT AGAIN:$' STROUT DB 0DH,0AH,'THE MINIUM IS:$'DATA ENDSSTACK SEGMENT STACK 'STACK'DW 100H DUP(0FFFFH)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTART PROC FARPUSH DSMOV AX,0PUSH AXMOV AX,DATAMOV DS,AXDISPSTR STRINAGAIN: MOV DX,OFFSET INSTR ;输入错误时重输入口MOV AH,0AHINT 21H ;用户输入字符串MOV SI,OFFSET NUMS ;SI指向数值起始位置MOV BX,DXADD BX,1 ;BX指向字符串长度字节MOV AL,[BX]MOV AH,0MOV CL,3DIV CL ;长度除以3得到有效数据个数CMP AH,0 ;余数不为0则输入必有误JNZ RESETMOV COUNT,ALMOV DX,0 ;DX压栈传递参数,初始为0,用于继续判断输入是否有误。

PUSH DXCALL CHECK ;调用过程CHECK继续判断输入是否有误POP DXCMP DX,1 ;弹出DX,DX得1时有误JE RESETCALL GETMIN ;调用过程找最小值DISPSTR STROUTMOV AH,0 ;此时CH中记载着最小数在数组中的偏移位置MOV AL,3 ;乘3得到在字符串中的偏移位置MUL CHMOV BX,AXADD BX,2DISPCH [BX]INC BXDISPCH [BX]DISPCH 0DHDISPCH 0AHRETRESET: DISPSTR STRERRJMP AGAINSTART ENDPCHECK PROC NEARMOV CH,0MOV CL,COUNTSUB CL,1 ;前COUNT-1次判断方式与最后一次略有不同INC BX ;BX指向字符串有实际意义的第一个字节LOOPCH: MOV AL,[BX] ;先判断前COUNT-1次,每一次循环判断连续三个字节AND AL,7FH ;最高位先置0CMP AL,'9' ;与'9'比大小,大则输入错误JA ERRORCMP AL,'0' ;与'0'比大小,小则输入错误JB ERRORSUB AL,'0' ;得到十位实际大小MOV DL,10MUL DL ;乘10放入DLMOV DL,ALINC BX ;BX后移一位MOV AL,[BX]AND AL,7FHCMP AL,'9'JA ERRORCMP AL,'0'JB ERRORSUB AL,'0'ADD DL,AL ;将个位的值累加到DL中,并将DL的值传给SI所指字节MOV [SI],DLINC SI ;SI指针后移MOV DL,0 ;DL重新置0INC BX ;BX继续后移MOV AL,[BX]AND AL,7FHCMP AL,' ' ;两数之间分隔符约定为','JNZ ERRORINC BX ;BX继续后移LOOP LOOPCHMOV AL,[BX] ;输入的最后三位的判断基本同上理,只是约定结束标志为'.' AND AL,7FHCMP AL,'9'JA ERRORCMP AL,'0'JB ERRORSUB AL,'0'MOV DL,10MUL DLMOV DL,ALINC BXMOV AL,[BX]AND AL,7FHCMP AL,'9'JA ERRORCMP AL,'0'JB ERRORSUB AL,'0'ADD DL,ALMOV [SI],DLINC SIMOV DL,0INC BXMOV AL,[BX]AND AL,7FHCMP AL,' 'JNZ ERRORJMP RETURNERROR: MOV BP,SP ;此时入栈的DX=0在SP+2处ADD BP,2MOV WORD PTR [BP],1 ;弹出DX后,DX将被置1RETURN: RETCHECK ENDPGETMIN PROC NEARMOV SI,OFFSET NUMS ;SI指向实际数值的偏移地址MOV DL,MIN ;DL记录已经比较过的数中的最小值MOV CL,COUNTLOOPF: CMP CL,0JZ RETU ;CL=0时结束循环CMP DL,[SI]JA GET ;若[SI]指向的值必现有最小值小则跳转DEC CL ;循环变量减1INC SI ;指针后移JMP LOOPFRETU: MOV MIN,DLRETGET: MOV DL,[SI] ;更新最小值INC SIMOV CH,COUNTSUB CH,CL ;CH=COUNT-CL记录新最小值的相对于NUMS的偏移地址DEC CL ;循环变量减1JMP LOOPFGETMIN ENDPCODE ENDSEND START五、程序运行结果六、回答预习题1.如何将输入的两个字符(0 – 9)变为十进制或二进制数?若想将连续两个0—9字符转换成十进制数,首先可以将第一个字符的ASCII码值减30H,得到实际的十位上的值。

相关主题