当前位置:文档之家› 【报告】汇编语言程序设计报告

【报告】汇编语言程序设计报告

【关键字】报告汇编语言程序设计报告计算机学院2011/6/7题目要求分支程序设计:1、编写程序,键入学生成绩(百分制),按A、B、C、D显示在屏幕上。

子程序设计:2、给定一个数组存放5个小写字母,用地址表传递方法编写子程序,将其转换成大写字母,并显示在屏幕上。

循环程序设计:3、设有一段文字,编写一段程序查找字母a出现的次数,并显示在屏幕上。

DOS功能调用:4、在图形方式下,在屏幕中央绘制一个用“*”表示的等腰三角形。

5、编写一个生成ASCII码表的程序,并显示在屏幕上。

6、根据提示输入任意年份,编写判断闰年的程序,如果是闰年,则在屏幕上显示“Y”,否则显示“N”。

7、显示杨辉三角形。

要求:(1)从键盘接收正整数n;(2)屏幕显示杨辉三角形,显示n行信息;编程思路:1.在数据段设置提示信息,成绩ABCD的显示信息,并预留空间。

利用DOS中断,取得输入的字符,输入字符的ASCII值在30H-39H之间为‘0-9’,不是则报错,值存入SCORE中,将SCORE的高位分别与9,8,7,6相比,跳转到设置好的代码区,输出对应成绩(A,B,C,D).若为3位数,则跳到A区,输出A.2. 在数据段设置ADDRESS存放数据偏移量和COUNT计数器利用DOS中断,取得输入的字符串存入DX中,偏移量存入STRING,并存入ADDRESS中。

COUNT存入ADDRESS+2地址中,调用子程序TURN,利用SI指针与ADDRESS配合将每个字母由大写转为小写。

3. 在数据段设置STRING用于存放键盘输入字符,COUNT存放字符个数,利用DOS中断,输入字符串存入STRING.编写CHECK模块用于检查输入的字符是否为a,循环执行CHECK模块,为a 则BL+1,不为a,SI+1继续检查,直至CX=0,最后输出结果。

4.堆栈段预留128字节空间存放*.设置SI控制空格数,BX为输出*个数.设置3层循环,分别输出空格数,*数,回车.首先将保护CX行数,将其压入栈中,外层循环按CX列数,输出每行之前的空格数,之后根据BX输出*,此时一行输入完,输出回车换行后,BX+2即*数+2,CX出栈,加入外循环,输出下一行信息。

5.初始化时设置行列数,第一个字符的ASCII值,设置两层循环,首先CX入栈保护输出行数,外层循环控制输出行数,内循环输出列个数对应的字符数,将要输入的字符存入DL,每输出完一次DL+1,SI值即列数给CX,当CX=0时,输出回车换行,CX出栈,加入外循环准备下一行的输出。

6.数据段设置提示信息,W存放输入年份的数值M,BUF存放年份字符串。

利用DOS中断,取得输入的年份字符串存入BUF中,字符个数存入CL,调用DATACATE把年份字符串转为16进制数值,在调用IFYEARS子模块判断其是否为闰年,输出相应信息。

DATACATE子模块总体设计思想,首先BUF+2给SI,利用循环,和SI指针从高位向低位逐个字符减去30H转为16进制数,将值存入W中。

IFYEARS 子模块总体设计思想,将W值给AX,判断能否被100整除,能则在判是否整除400,能则为闰年,不能则不是闰年。

若不能整除100,判是否整除4,能则为闰年,不能则不是,输出相应信息。

7.数据段设置BUF用于存放三角中的数。

总体思想:基于组合数计算杨辉三角,即c(m,n)的输出。

设置两层循环控制输出的行列,一重循环系数m,范围1-n,二重循环系数n,范围1-m。

利用DOS中断,将输入n存入num中。

主程序:内循环调用store将每行三角中的每个值存入buf中,调用外循环加入下一行。

子程序store:由ch,cl传递参数m,n,求组合数C(m,n),并转换为10进制数存入buf中,再写入一个空格。

子程序multiply:由bh,bl传递参数p,q,求乘积p(p-1)(p-2)...(p-q+1),并由dx传出。

流程图:1. 分支程序设计:2. 子程序设计:3. 循环程序设计:4. DOS功能调用:5.ASCII表输出6.判断闰年7.杨辉三角输出源程序:1.DATASTRINGSARBRCRDSCOREDATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXMOV DX,OFFSET STRING;MOV AH,9INT 21H;提示输入成绩,显示字符串,DS:DX=串首址MOV DX,OFFSET SCORE;返回SCORE所在段偏移量MOV AH,0AHINT 21H;输入4个成绩MOV DX,OFFSET SMOV AH,9INT 21H;CMP AL, 30HJB ERRORCMP AL, 39HJA ERRORMOV BL,[SCORE+1]CMP BL,03HJZ AARMOV BL,[SCORE+2]CMP BL,39HJZ AARMOV BL,[SCORE+2]CMP BL,38HJZ EIGHTMOV BL,[SCORE+2]SUB BL,37HJZ BBRMOV BL,[SCORE+2]CMP BL,36HJZ CCRJMP DDR ;不及格EIGHT:MOV BL,[SCORE+3] ;80分段的判断SUB BL,35HJAE AARJMP BBRERROR :MOV AH, 09 ;错误提示MOV DX, OFFSET MESSAGEINT 21HJMP STARTAAR: MOV DX,OFFSET RAJMP EXITBBR: MOV DX,OFFSET RBJMP EXITCCR: MOV DX,OFFSET RCJMP EXITDDR: MOV DX,OFFSET RDJMP EXITEXIT:MOV AH,9INT 21HMOV AH,4CHINT 21HCODE ENDSEND START2.DATA SEGMENTADDRESS DW 0,0STRING DB 6HDB ?DB 6H DUP(?),'$'COUNT DW 0ENT DB 13,10,'$'DATA ENDSSTACK1 SEGMENT PARA STACKDW 20H DUP(0)STACK1 ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACK1START: MOV AX,DATAMOV DS,AXMOV DX,OFFSET STRINGMOV AH,0AHINT 21HMOV ADDRESS,OFFSET STRING ; ADDRESS存放偏移量MOV BX,OFFSET STRINGMOV DH,0MOV DL,[BX+1] ;将字符个数存入COUNTMOV COUNT,DXMOV ADDRESS+2,OFFSET COUNT ;ADDRESS+2里存的为COUNTCALL TURN ;小写转大写模块MOV DX,OFFSET ENTMOV AH,9INT 21HMOV DX,OFFSET STRING+2MOV AH,09HINT 21HMOV AH,4CHINT 21HTURN PROC NEARPUSH SIPUSH BXPUSH DIPUSH CXMOV BX,OFFSET ADDRESSMOV SI,[BX]ADD SI,02HMOV DI,[BX+2] ;BX+2 里存入的为字符个数MOV CX,[DI]L: SUB byte ptr [SI],20HINC SILOOP L ;利用指针循环(CX控制)转变POP CXPOP DIPOP BXPOP SIRETENDPCODE ENDSEND START3.DATA SEGMENTSTRING DB 100DB ?DB 100 DUP(?)COUNT EQU $-STRINGDATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AXMOV DX,OFFSET STRINGMOV AH,0AHINT 21HMOV SI,OFFSET STRING + 2MOV BL,0MOV CX,COUNTMOV DH,61HCHECK: CMP [SI],DHJNE NEXTINC BLNEXT: INC SILOOP CHECKADD BL,30HMOV DL,0AHMOV AH,02HINT 21HMOV DL,0DHMOV AH,02HMOV DL,BLMOV AH, 02HINT 21HMOV AH,4CHINT 21HCODE ENDSEND START 4.STACK SEGMENTDB 128(?)STACK ENDSCODE SEGMENTASSUME CS:CODESTART:MOV SI,5;控制空格数MOV BX,1;BX控制输出*MOV CX,4;OUTLOOP: PUSH CX;保护列数MOV CX,SIMOV DL,20H;输出空格SPL: MOV AH,2HINT 21HLOOP SPLMOV CX,BXMOV DL,2AH;输出*STL: MOV AH,2HINT 21HLOOP STLMOV DL,0DH;输出回车MOV AH,02HINT 21HMOV DL,0AH;换行MOV AH,02HINT 21HDEC SIADD BX,2;多一行*数加2POP CXLOOP OUTLOOP;进下一行MOV AH,4CHINT 21HCODE ENDSEND START5.CODE SEGMENTASSUME CS:CODESTART: MOV SI,10H0 ;列数16MOV CX,7 ;行数7MOV BL,20H ;第一个字符的ASCII代码LOOP1: PUSH CX ;入栈保护循环数,控制行数MOV CX,SI;CX为每行输出个数LOOP2: MOV DL,BLMOV AH,2INT 21H;在屏幕上显示第一个字符MOV DL,20HMOV AH,2INT 21H;在屏幕上显示第一个ASCII代码INC BL;BL加1即ASCII代码加1LOOP LOOP2;循环,准备显示下一个ASCII码字符MOV DL,0AHMOV AH,2HINT 21H ;一行显示完,输出一个回车符MOV DL,0DHMOV AH,2INT 21H ;输出一个换行符POP CX ;一行输完,cx出栈LOOP LOOP1 ;循环,准备显示下一行ASCII码字符MOV AH,4CHINT 21HCODE ENDSEND START6.DATA SEGMENTINFON DB 0DH,0AH,'Please input a year: $'Y DB 0DH,0AH,'This is a leap year! $'N DB 0DH,0AH,'This is not a leap year! $'W DW 0 ;用于保存输入的年份的数值BUF DB 8DB ?DB 8 DUP(?)DATA ENDSSTACK SEGMENT STACKDB 200 DUP(0)STACK ENDSCODE SEGMENTASSUME DS:DATA,SS:STACK,CS:CODESTART: MOV AX,DATAMOV DS,AXLEA DX,INFON ;在屏幕上显示提示信息MOV AH,9 ;显示字符串INT 21HLEA DX,BUF ;从键盘输入年份字符串MOV AH,0AH ;0AH功能调用从键盘接受字符串到内存的输入缓存区INT 21HXOR CH,CH ;ch要清0,否则循环次数有误.MOV CL, BUF+1 ;把输入的字符的个数保存在cl中CALL DATACATE ;调用datacate子程序把表示年份的字符串转换为数值CALL IFYEARS ;调用ifyears子程序判断闰年JC A1 ;进位标志1 为闰年LEA DX,NMOV AH,9INT 21HJMP EXITA1: LEA DX,YMOV AH,9INT 21HEXIT: MOV AH,4CHINT 21HDATACATE PROC NEAR ;把表示年份的字符串转换为数值PUSH CXDEC CXLEA SI,BUF+2TT1: INC SILOOP TT1POP CX ;从高位向低位逐个MOV AX,1L1: PUSH AXMOV DH,30HMOV BX,10MOV DL,[SI] ;字符减去30H后即可转换为十六进制数XOR DH,DHMUL DXADD W,AXPOP AXMUL BXDEC SILOOP L1RETDATACATE ENDPIFYEARS PROC NEARPUSH BXPUSH CXPUSH DXMOV AX,WMOV DX,0MOV BX,100DIV BXCMP DX,0JE NEXT ;能被400整除,判能否被400整除XOR DX,DXMOV AX,WMOV BX,4DIV BXCMP DX,0JE LAB2JMP LAB1NEXT:XOR DX,DXMOV AX,WMOV BX,400DIV BXCMP DX,0JE LAB2JMP LAB1LAB1: CLC ;进位标志置0JMP LAB3LAB2: STCLAB3: POP DXPOP CXPOP BXRETIFYEARS ENDPCODE ENDS7.data segmentbuf db 200 dup()endscode segmentstart:lea di,bufmov ch,00h ;ch为一重循环系数m,范围1-9loop_m:mov cl,00h ;cl为二重循环系数n,范围1-mmov al,0ahstosbmov al,0dhstosbinc chloop_n:call storeinc clcmp cl,chjbe loop_ncmp ch,09hjb loop_mmov [di],'$'finish:lea dx,bufmov ah,09hint 21hmov ah,4chint 21h;子程序store:由ch,cl传递参数m,n,求组合数C(m,n) ;并转换为10进制数存入buf中,再写入一个空格store proc nearpush axpush bxpush cxpush dx;将n和m-n中较小者赋给cl,减小运算量mov bl,chsub bl,clcmp cl,bljbe nextmov cl,blnext:jne next1;n为0或n=m时直接往buf中写入1mov al,01hadd al,'0'stosbmov al,' 'stosbpop dxpop cxpop bxpop axretnext1: ;n!=0且n!=m时调用子过程计算mov bh,chmov bl,cl;调用子过程multiply求分子call multiplymov ax,dxmov bh,cl;调用子过程multiply求分母call multiplydiv dl ;此时计算结果在al中mov ah,0mov dl,64hdiv dl ;百位在al中,十位个位在ah中cmp al,0je next2add al,'0'mov [di],alinc dinext2:mov al,ahmov ah,0mov dl,0ahdiv dl ;十位在al中,个位在ah中cmp al,0je next3add al,'0'stosbnext3:add ah,'0'mov [di],ahinc distosbpop dxpop cxpop bxpop axretstore endp;子程序multiply:由bh,bl传递参数p,q;求乘积p(p-1)(p-2)...(p-q+1),并由dx传出multiply proc nearpush axpush bxpush cxmov cx,0mov cl,blmov bl,bhmov bh,0mov ax,1mov dx,0loop_mult:mul bxdec bxloop loop_multmov dx,axpop cxpop bxpop axretmultiply endpcode endsend start输出屏幕截图:1. 分支程序设计:输出成绩A,B,C,D2. 子程序设计:小写变大写3. 循环程序设计:输出a出现的次数4. DOS功能调用:输出等腰”*”三角形5.输出ACSII表6.判断闰年7. 输出杨辉三角汇编自学课程心得:接触汇编语言之前,我们在计算机组成原理课程中就已经有所了解了,但也只是略微明白一些如jmp,mov这样的指令,极度缺乏系统性的学习。

相关主题