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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【关键字】报告
汇编语言程序设计报告
计算机学院
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.
DATA
STRING
S
A
RB
RC
RD
SCORE
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET STRING;
MOV AH,9
INT 21H;提示输入成绩,显示字符串,DS:DX=串首址
MOV DX,OFFSET SCORE;返回SCORE所在段偏移量
MOV AH,0AH
INT 21H;输入4个成绩
MOV DX,OFFSET S
MOV AH,9
INT 21H;
CMP AL, 30H
JB ERROR
CMP AL, 39H
JA ERROR
MOV BL,[SCORE+1]
CMP BL,03H
JZ AAR
MOV BL,[SCORE+2]
CMP BL,39H
JZ AAR
MOV BL,[SCORE+2]
CMP BL,38H
JZ EIGHT
MOV BL,[SCORE+2]
SUB BL,37H
JZ BBR
MOV BL,[SCORE+2]
CMP BL,36H
JZ CCR
JMP DDR ;不及格
EIGHT:
MOV BL,[SCORE+3] ;80分段的判断
SUB BL,35H
JAE AAR
JMP BBR
ERROR :
MOV AH, 09 ;错误提示
MOV DX, OFFSET MESSAGE
INT 21H
JMP START
AAR: MOV DX,OFFSET RA
JMP EXIT
BBR: MOV DX,OFFSET RB
JMP EXIT
CCR: MOV DX,OFFSET RC
JMP EXIT
DDR: MOV DX,OFFSET RD
JMP EXIT
EXIT:
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
2.
DATA SEGMENT
ADDRESS DW 0,0
STRING DB 6H
DB ?
DB 6H DUP(?),'$'
COUNT DW 0
ENT DB 13,10,'$'
DATA ENDS
STACK1 SEGMENT PARA STACK
DW 20H DUP(0)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET STRING
MOV AH,0AH
INT 21H
MOV ADDRESS,OFFSET STRING ; ADDRESS存放偏移量
MOV BX,OFFSET STRING
MOV DH,0
MOV DL,[BX+1] ;将字符个数存入COUNT
MOV COUNT,DX
MOV ADDRESS+2,OFFSET COUNT ;ADDRESS+2里存的为COUNT
CALL TURN ;小写转大写模块
MOV DX,OFFSET ENT
MOV AH,9
INT 21H
MOV DX,OFFSET STRING+2
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
TURN PROC NEAR
PUSH SI
PUSH BX
PUSH DI
PUSH CX
MOV BX,OFFSET ADDRESS
MOV SI,[BX]
ADD SI,02H
MOV DI,[BX+2] ;BX+2 里存入的为字符个数
MOV CX,[DI]
L: SUB byte ptr [SI],20H
INC SI
LOOP L ;利用指针循环(CX控制)转变
POP CX
POP DI
POP BX
POP SI
RET
ENDP
CODE ENDS
END START
3.
DATA SEGMENT
STRING DB 100
DB ?
DB 100 DUP(?)
COUNT EQU $-STRING
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET STRING
MOV AH,0AH
INT 21H
MOV SI,OFFSET STRING + 2
MOV BL,0
MOV CX,COUNT
MOV DH,61H
CHECK: CMP [SI],DH
JNE NEXT
INC BL
NEXT: INC SI
LOOP CHECK
ADD BL,30H
MOV DL,0AH
MOV AH,02H
INT 21H
MOV DL,0DH
MOV AH,02H
MOV DL,BL
MOV AH, 02H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START 4.
STACK SEGMENT
DB 128(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE
START:
MOV SI,5;控制空格数
MOV BX,1;BX控制输出*
MOV CX,4;OUTLOOP: PUSH CX;保护列数
MOV CX,SI
MOV DL,20H;输出空格SPL: MOV AH,2H
INT 21H
LOOP SPL
MOV CX,BX
MOV DL,2AH;输出*
STL: MOV AH,2H
INT 21H
LOOP STL
MOV DL,0DH;输出回车
MOV AH,02H
INT 21H
MOV DL,0AH;换行
MOV AH,02H
INT 21H
DEC SI
ADD BX,2;多一行*数加2
POP CX
LOOP OUTLOOP;进下一行
MOV AH,4CH
INT 21H
CODE ENDS
END START
5.
CODE SEGMENT
ASSUME CS:CODE
START: MOV SI,10H0 ;列数16
MOV CX,7 ;行数7
MOV BL,20H ;第一个字符的ASCII代码
LOOP1: PUSH CX ;入栈保护循环数,控制行数
MOV CX,SI;CX为每行输出个数
LOOP2: MOV DL,BL
MOV AH,2
INT 21H;在屏幕上显示第一个字符
MOV DL,20H
MOV AH,2
INT 21H;在屏幕上显示第一个ASCII代码
INC BL;BL加1即ASCII代码加1
LOOP LOOP2;循环,准备显示下一个ASCII码字符
MOV DL,0AH
MOV AH,2H
INT 21H ;一行显示完,输出一个回车符
MOV DL,0DH
MOV AH,2
INT 21H ;输出一个换行符
POP CX ;一行输完,cx出栈
LOOP LOOP1 ;循环,准备显示下一行ASCII码字符
MOV AH,4CH
INT 21H
CODE ENDS
END START
6.
DATA SEGMENT
INFON 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 8
DB ?
DB 8 DUP(?)
DATA ENDS
STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME DS:DATA,SS:STACK,CS:CODE
START: MOV AX,DATA
MOV DS,AX
LEA DX,INFON ;在屏幕上显示提示信息
MOV AH,9 ;显示字符串
INT 21H
LEA DX,BUF ;从键盘输入年份字符串
MOV AH,0AH ;0AH功能调用从键盘接受字符串到内存的输入缓存区
INT 21H
XOR CH,CH ;ch要清0,否则循环次数有误.
MOV CL, BUF+1 ;把输入的字符的个数保存在cl中
CALL DATACATE ;调用datacate子程序把表示年份的字符串转换为数值
CALL IFYEARS ;调用ifyears子程序判断闰年
JC A1 ;进位标志1 为闰年
LEA DX,N
MOV AH,9
INT 21H
JMP EXIT
A1: LEA DX,Y
MOV AH,9
INT 21H
EXIT: MOV AH,4CH
INT 21H
DATACATE PROC NEAR ;把表示年份的字符串转换为数值
PUSH CX
DEC CX
LEA SI,BUF+2
TT1: INC SI
LOOP TT1
POP CX ;从高位向低位逐个
MOV AX,1
L1: PUSH AX
MOV DH,30H
MOV BX,10
MOV DL,[SI] ;字符减去30H后即可转换为十六进制数
XOR DH,DH
MUL DX
ADD W,AX
POP AX
MUL BX
DEC SI
LOOP L1
RET
DATACATE ENDP
IFYEARS PROC NEAR
PUSH BX
PUSH CX
PUSH DX
MOV AX,W
MOV DX,0
MOV BX,100
DIV BX
CMP DX,0
JE NEXT ;能被400整除,判能否被400整除
XOR DX,DX
MOV AX,W
MOV BX,4
DIV BX
CMP DX,0
JE LAB2
JMP LAB1
NEXT:
XOR DX,DX
MOV AX,W
MOV BX,400
DIV BX
CMP DX,0
JE LAB2
JMP LAB1
LAB1: CLC ;进位标志置0
JMP LAB3
LAB2: STC
LAB3: POP DX
POP CX
POP BX
RET
IFYEARS ENDP
CODE ENDS
7.
data segment
buf db 200 dup()
ends
code segment
start:
lea di,buf
mov ch,00h ;ch为一重循环系数m,范围1-9
loop_m:
mov cl,00h ;cl为二重循环系数n,范围1-m
mov al,0ah
stosb
mov al,0dh
stosb
inc ch
loop_n:
call store
inc cl
cmp cl,ch
jbe loop_n
cmp ch,09h
jb loop_m
mov [di],'$'
finish:
lea dx,buf
mov ah,09h
int 21h
mov ah,4ch
int 21h
;子程序store:由ch,cl传递参数m,n,求组合数C(m,n) ;并转换为10进制数存入buf中,再写入一个空格store proc near
push ax
push bx
push cx
push dx
;将n和m-n中较小者赋给cl,减小运算量
mov bl,ch
sub bl,cl
cmp cl,bl
jbe next
mov cl,bl
next:
jne next1
;n为0或n=m时直接往buf中写入1
mov al,01h
add al,'0'
stosb
mov al,' '
stosb
pop dx
pop cx
pop bx
pop ax
ret
next1: ;n!=0且n!=m时调用子过程计算mov bh,ch
mov bl,cl
;调用子过程multiply求分子
call multiply
mov ax,dx
mov bh,cl
;调用子过程multiply求分母
call multiply
div dl ;此时计算结果在al中
mov ah,0
mov dl,64h
div dl ;百位在al中,十位个位在ah中
cmp al,0
je next2
add al,'0'
mov [di],al
inc di
next2:
mov al,ah
mov ah,0
mov dl,0ah
div dl ;十位在al中,个位在ah中
cmp al,0
je next3
add al,'0'
stosb
next3:
add ah,'0'
mov [di],ah
inc di
stosb
pop dx
pop cx
pop bx
pop ax
ret
store endp
;子程序multiply:由bh,bl传递参数p,q
;求乘积p(p-1)(p-2)...(p-q+1),并由dx传出
multiply proc near
push ax
push bx
push cx
mov cx,0
mov cl,bl
mov bl,bh
mov bh,0
mov ax,1
mov dx,0
loop_mult:
mul bx
dec bx
loop loop_mult
mov dx,ax
pop cx
pop bx
pop ax
ret
multiply endp
code ends
end start
输出屏幕截图:
1. 分支程序设计:输出成绩A,B,C,D
2. 子程序设计:小写变大写
3. 循环程序设计:输出a出现的次数
4. DOS功能调用:输出等腰”*”三角形
5.输出ACSII表
6.判断闰年
7. 输出杨辉三角
汇编自学课程心得:
接触汇编语言之前,我们在计算机组成原理课程中就已经有所了解了,但也只是略微明白一些如jmp,mov这样的指令,极度缺乏系统性的学习。

感触最深的一点是在C语言中不到10个语句构成的程序,用汇编语言却要好几十行甚至上百行。

这不得不让我们对汇编产生一种恐惧感。

学习汇编语言能让我们更加了解计算机内部的组织结构,对我们计算机专业的学生来说,学习汇编也是提升综合能力的关键环节。

,习汇编语言,首要问题是学习80X86指令系统。

如果能将指令系统中的各个助记符、格式等都能完全掌握并灵活运用,大部分工作就已经完成了。

指令系统确定了CPU所能完成的功能,是用汇编语言进行程序设计的最基本部分。

如果不熟悉汇编指令的功能及其有关规定,那肯定不能灵活使用汇编语言。

在编写汇编程序时,应该注意特别容易出现的错误,例如在编写数据传送指令时,目的操作数和源操作数的类型一定要匹配,CS不能作为目的操作数,offset后只能跟简单地址符号,等等。

汇编语言中的程序结构,子程序等知识也会帮助我们编写出一个更加完善的汇编程序。

另外,在编程中,我们还用到了DOS系统功能调用。

在学习汇编语言时,指令的功能是学习和掌握的重点,要准确有效并合理的使用这些指令,必须了解一些使用的规则。

现对汇编语言编程时的规则进行总结,归纳起来有三点:1、要求指令操作数的寻址方式;2、指令对标志位的影响和标志位对指令的影响;3、指令的执行时间,对可完成同样功能的指令,要选用执行时间短的指令。

要学好汇编语言,实验是必不可少的环节。

我们深有体会:书上的程序都能看懂,基本原理也都明白,但是在自己亲手编写程序时,却无从下手,甚至连第一句该怎么写都不知道。

通过实验,可以在很大程度上加深印象。

在书上看程序,一切都是理所当然,十分顺利,而自己动手,才会真正发现自己的不足之处。

程序的编写在记事本中进行即可,掌握debug
的使用对实验是有很大帮助的。

现在汇编语言的自学课程已经告一段落了,学习过程中遇到的所有困难以及遗留的难点都需要我们在其余时间里逐步攻克,在打好基础的前提下,学习更加专业的汇编知识。

此文档是由网络收集并进行重新排版整理.word可编辑版本!。

相关文档
最新文档