北邮汇编语言实验报告
微机原理汇编实验一
专 业计算机科学与技术 班 级
学 生
学 号
目 录
一、实验要求...................................................................3 二、实验设计...................................................................3
1.分析及算法思想...................................................................3
2.数据结构...............................................................................3
3.子程序...................................................................................4 4.流程图...................................................................................4
三、运行实例..................................................................6
四、实验总结..................................................................6
五、附页(源代码).......................................................7
一、实验要求:
一个学生的信息包括姓名、班级、学号(班内序号)、成绩。试编写程序实现以下功能:
(1)能录入学生成绩(十进制形式);提示:输入形如:tom 301 16 95回车,每名学生用一行,选择一个特殊符表示输入结束;
(2)能按要求:如学号或成绩进行排序显示;
(3)能统计平均成绩;
(4)能统计不及格、60-70、70-80、80-90、90-100各分数段的人数。
二、实验设计:
1.分析及算法思想:
(1)采用数组进行数据存储:学生数目信息数组(存储学生数目),学生信息数组(按班级-学号-姓名格式存储),平均成绩数组。五个DB变量记录各分数段人数。
(2)输入学生数目保存在数组中,提示输入学生信息并存储,对于字符串输入进行转换,以二进制的形式存储在数据段中。采用冒泡排序对数据段中的人员信息进行排序,以成绩为参数进行遍历,统计各分数段人数并将同时求出平均成绩,输出运算结果。
2.数据结构:
(1)输入:
a. 学生数目数组number db 3 dup(0)
说明:第一个存个/十位(ASCII码),第二个存个位(ASCII码),第 三个存学生数(二进制)
b. 学生信息数组information db 99 dup(20 dup(0))
说明:用20字节单元表示学生信息,0-19中:0对应最大字符,
1对应实际输入,2-18对应输入信息,19对应'$'
c.成绩数组grade db 99 dup(7 dup(0))
说明:第一个存整数部分(二进制形式),第二个存小数部分(二进 制形式)
d.平均成绩数组average_grade_buffer db 2 dup(0)
说明:和成绩数组原理一样
(2)排序:(按成绩分布排序)
(3)提示信息:
Student_num:提示输入学生数目
student_information:提示输入学生信息
student_grade:提示输入成绩信息
average_grade:提示输出平均成绩
grade_rank:提示输出成绩排名
Result1:(90-100)分数段人数
Result2:(80-90)分数段人数
Result3:(70-80)分数段人数
Result4:(60-70)分数段人数
Result5:(0-60)分数段人数
blank :输出空格,便于查看结果
huanhang:输出换行,便于查看结果
3.子程序:
(1)store_student_num 存储用户输入的学生数目;
(2)store_student_information存储学生姓名和班级和学号;
(3)store_student_grade存储学生成绩;
(4)sort排序学生成绩的函数;
(5)find_result显示最后结果的函数;
(6)display输出分数排序的函数。
(7)show将二进制数(不大于127的十进制整数)输出的函数
4.流程图:
三、运行实例:
输入四个学生的信息:结果如下
四、实验总结
通过这次的汇编程序,我从中学习到了很多知识。虽然刚开始的时候遇到了很多难题,但是通过与老师、同学的交流之后,逐步克服了一个个的难题。提高了自己编程的思维能力,在将来的学习,生活之中能够快速的解决问题。汇编相对于别的编程语言而言,难度是比较大。汇编是直接对CUP进行操作,能够直接控制计算机编程。由于汇编不像JAVA 那样的高级编程语言面向对象,在编程的时候思维有点乱,容易出错,而且小的错误也不容易找到,特别是程序代码长的时候。
五、附页(源代码)
;输入学生数目格式:1到99的整数
;输入学生信息格式:班级(class)-学号(NUM)—姓名(NAME),班级最多5位,学号最多5位,姓名最多6位,加上1位中间分隔符 —
;输入学生成绩格式:0.0-100.0 最多一位小数
;
;!!!警告:任何错误的输入都将导致程序运行失败或错误!!!
;
;
;#######################################################数据段开始 DATAS SEGMENT ;此处输入数据段代码
;;; 输入输出提示字符
student_num db 'Please input the number of students(1-99):',0dh,0ah,'$'
student_information db 0dh,0ah,'Please input the student information(CLASS-NUM-NAME):',0dh,0ah,'$'
student_grade db 0dh,0ah,'Please input the student grade(0.0-100.0):',0dh,0ah,'$'
average_grade db 0dh,0ah,'The average grade is:',0dh,0ah,'$'
result1 db 0dh,0ah,'The number of student in [Up 90] is:',0dh,0ah,'$' ;各分数段人数
result2 db 0dh,0ah,'The number of student in [80-90] is:',0dh,0ah,'$'
result3 db 0dh,0ah,'The number of student in [70-80] is:',0dh,0ah,'$'
result4 db 0dh,0ah,'The number of student in [60-70] is:',0dh,0ah,'$'
result5 db 0dh,0ah,'The number of student in [Below 60] is:',0dh,0ah,'$'
grade_rank db 0dh,0ah,'The grade rank(from high to low)is:',0dh,0ah,'$' ;打印排名
blank db ' ','$'
huanhang db 0dh,0ah,'$'
kaishishuchu db 0dh,0ah,'***********************************',0dh,0ah,'$'
;数据
number db 3 dup(0) ;第一个存个/十位(ASCII码),第二个存个位(ASCII码),第三个存学生数(二进制)
;用20字节单元表示学生信息,0-19中:0对应最大字符,1对应实际输入,2-18对应输入信息,19对应'$'
information db 99 dup(20 dup(0))
;用7字节单元来存分数,0-6中,0-4对应输入字符,5对应输入整数部分的二进制数,6对应于小数部分的二进制数
grade db 99 dup(7 dup(0))
average_grade_buffer db 2 dup(0) ;第一个存整数部分(二进制形式),第二个存小数部分(二进制形式)
n0 db 0 ;各分数段人数存储区(二进制形式)
n1 db 0
n2 db 0
n3 db 0
n4 db 0
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START: ;此处输入代码段代码
MOV AX,DATAS
MOV DS,AX
mov si,0 ;指向每个学生信息
mov di,0 ;指向每个学生成绩
mov cx,100 ;初始化学生数
mov dx, offset student_num ;请求输入学生总数
mov ah,09
int 21h
call store_student_num ;存储学生总数,结果送cx中
cmp cx,0 ;输入为0退出
jle OutToDOS
cmp cx,100 ;学生数超出本程序范围,退出
jge OutToDOS
input:
mov dx, offset student_information ;请求输入学生信息 mov ah,09
int 21h
call store_student_information ;存储学生信息
add si,20 ;指向下一个学生信息
mov dx, offset student_grade ;请求输入学生成绩
mov ah,09
int 21h
call store_student_grade ;存储每个学生成绩
add di,7 ;指向下一个学生
loop input ;循环,直到输入所有学生成绩
call sort ;排序
call find_result ;显示平均成绩和分段人数
call display ;显示排序结果
OutToDOS:
mov ah,1 ;任意键结束
int 21h
mov ax,4c00h ;返回DOS
int 21h
;##########存储学生数目的函数
store_student_num proc ;调用之后,cx中存储了学生数(二进制) push ax
push bx
mov bx,0
s1:
mov ah,1
int 21h
cmp al,0dh ;是否为回车
je s2
and al,0fh ;转换为非压缩的BCD码
mov number[bx],al
inc bx
jmp s1
s2:
cmp bx,2
jg s5 ;大于2
jz s3 ;等于2
;小于2
mov al,number
jmp s4
s3:
mov ah,number
mov al,number+1
aad ;BCD码转换为二进制数
s4:
mov number+2,al
mov cl,number+2
s5:
pop bx
pop ax
ret
store_student_num endp
;##########存储学生信息的函数
store_student_information proc
push ax
push bx
push dx
mov al,18
mov information[si],al
lea dx,information[si]
mov ah,0ah
int 21h
mov bl,information[si + 1]
mov al,' '
mov information[si + bx + 2],al
mov information[si+19],'$'
'$'以便输出
pop dx
pop bx
pop ax
ret
store_student_information endp
;##########存储学生成绩的函数
store_student_grade proc
push ax
push bx
push cx
push dx
mov bx,0 ;实际输入的字符个数 ;将回车换成' ' ;将每个存储单元的最后一个字节置为
mov dx,di
deal0:
mov ah,1
int 21h
cmp al,0dh ;判断是否为回车
jz deal2 ;是回车
cmp al,'.' ;是否为小数点
jnz deal1 ;不是小数点
mov bx,cx ;bx指向小数点处
inc bx ;标记小数点字符出现在第几个位置
deal1:
push bx
mov bx,dx
mov grade[bx],al
pop bx
inc cx ;记录输入字符的个数
inc dx
jmp deal0
deal2:
cmp bx,0
jnz deal3 ;有小数点
;无小数点
cmp cx,3
jg gout ;大于100
jz deal4 ;等于100
;小于100
cmp cx,2
jz deal5 ;输入数目为2位数
;个位数
deal6: ;处理个位数
mov al,grade[di]
sub al,'0'
mov grade[di + 5],al
jmp gout
deal5: ;处理2位数
mov ah,grade[di]
and ah,0fh
mov al,grade[di + 1]
and al,0fh
aad
mov grade[di + 5],al
jmp gout
deal4: ;处理3位数
mov al,100
mov grade[di + 5],al
jmp gout
deal3: ;处理带有小数部分的成绩
mov al,grade[di + bx] ;将小数部分处理
sub al,'0'
mov grade[di + 6],al
cmp bx,4
jz deal4 ;'.'出现在输入字符的第四位,则输入的整数部分为3位数
jg gout ;整数部分大于3位数
cmp bx,3
jz deal5 ;'.'出现在输入字符的第三位,则输入的整数部分为2位数
jmp deal6 ;否则为个位数
gout:
pop dx
pop cx
pop bx
pop ax
ret
store_student_grade endp
;##########排序学生成绩的函数
sort proc
push ax
push bx
push cx
push dx
push si
push di
mov dx,0
mov dl,number+2
Loop1: ;使用冒泡排序法
mov cx,dx
mov di,0
mov si,0
Loop2: ;先比整数部分,再比小数部分
mov al,grade[di + 5]
cmp al,grade[di + 12]
jg next ;大于,向下个移动
jl swap1 ;小于,交换成绩,名字
;等于,比较小数部分
mov al,grade[di + 6]
cmp al,grade[di + 13]
jge next ;大于或等于,向下个移动
jl swap1 ;小于,交换成绩,名字
swap1:
mov bx,si
swap11: ;交换学生信息
mov al,information[bx + 2]
xchg al,information[bx + 22]
mov information[bx + 2],al
inc bx
cmp al,'$'
jnz swap11
push bx
mov bx,0
swap2: ;交换学生成绩
mov al,grade[di + bx]
xchg al,grade[di + bx + 7]
mov grade[di + bx],al
inc bx
cmp bx,7
jnz swap2
pop bx
next:
add si,20
add di,7
dec cx
jnz Loop2
dec dx
jnz Loop1
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
sort endp
;##########显示最后结果的函数
find_result proc
push ax
push bx
push cx
push dx
push si
push di
mov bx,0
mov cx,0
mov cl,number+2 ;cl中保存学生人数
mov di,0
mov si,0
F1:
mov al,grade[di + 5]
cmp al,100
jg Fout ;大于100
jz F90 ;等于100
;小于100
cmp al,90
jge F90 ;大于等于90
;小于90
cmp al,80
jge F80 ;大于等于80
;小于80
cmp al,70
jge F70 ;大于等于70
;小于70
cmp al,60
jge F60 ;大于等于60
;小于60
;处理
mov dl,n4
inc dl
mov n4,dl
Fnext: ;处理平均成绩 处理方式:整数部分*10+小数部分*10,结果先除以学生人数,再输出(输出整数时除以10)
mov al,grade[di + 5]
mov dl,10
mul dl
mov dl,grade[di + 6]
mov dh,0
add ax,dx
add bx,ax
jmp F2
F90: ;处理>=90
mov dl,n0
inc dl
mov n0,dl
jmp Fnext
F80: ;处理大于等于80小于90
mov dl,n1
inc dl
mov n1,dl
jmp Fnext
F70: ;处理大于等于70小于80
mov dl,n2
inc dl
mov n2,dl
jmp Fnext
F60: ;处理大于等于60小于70
mov dl,n3
inc dl
mov n3,dl
jmp Fnext
F2:
add di,7
dec cx
jnz F1 ;处理所有学生
mov dx,offset kaishishuchu ;打印一段************
mov ah,09
int 21h
mov dx,offset average_grade ;打印平均成绩
mov ah,09
int 21h
mov ax,bx
mov dx,0
mov cx,0
mov cl,number+2
div cx
mov cl,10
div cl
call show ;先打印平均成绩的整数部分
push ax
mov dl,'.' ;打印'.'
mov ah,2
int 21h
pop ax
mov al,ah
call show ;再打印平均成绩的小数部分
mov dx,offset result1 ;输出大于等于90的人数
mov ah,09
int 21h
mov al,n0
call show
mov dx,offset result2 ;输出大于等于80并小于90的人数
mov ah,09
int 21h
mov al,n1
call show
mov dx,offset result3 ;输出大于等于70并小于80的人数 mov ah,09
int 21h
mov al,n2
call show
mov dx,offset result4
mov ah,09
int 21h
mov al,n3
call show
mov dx,offset result5
mov ah,09
int 21h
mov al,n4
call show
Fout:
pop di
pop si
pop dx
pop cx
pop bx
pop ax
ret
find_result endp
;##########输出分数排序的函数
display proc
push ax ;输出大于等于60并小于70的人数 ;输出小于60的人数
push cx
push dx
push si
push di
mov dx, offset grade_rank
mov ah,09
int 21h
mov cx,0
mov cl,number+2 ;cl中保存学生人数
mov di,0
mov si,0
D1:
lea dx, offset information
add dx,si
add dx,2
mov ah,09
int 21h
mov dx, offset blank ;打印一段空白
mov ah,09
int 21h
mov grade[di + 5],'$' ;将保存成绩的单元中第6个字节置为'$',便于输出
mov dx, offset grade ;输出成绩
add dx,di
mov ah,09
int 21h
mov dx, offset huanhang ;打印换行
mov ah,09
int 21h
add si,20
add di,7
dec cx
jnz D1 ;直至将所有成绩都输出
pop di
pop dx
pop cx
pop bx
pop ax
ret
display endp
;##########将二进制数(不大于127的十进制整数)输出的函数
show proc
push ax
push dx
push cx
push bx
mov cl,100
mov ah,0
div cl ;将al中的二进制数除以100
mov bx,ax ;保存余数
cmp al,0
jz x1 ;如果商为0,则表示原数小于100
;否则将百位数打印出来
mov dl,al
add dl,30h
mov ah,2
int 21h
x1:
mov al,bh
mov ah,0
mov cl,10
div cl ;将al中的二进制数除以10
mov bx,ax ;保存余数
cmp al,0
jz x2 ;如果商为0,则表示原数小于10
;否则将十位打印出来
mov dl,al
add dl,30h
mov ah,2
int 21h
x2: ;打印个位
mov dl,bh
add dl,30h
mov ah,2
int 21h
pop bx
pop cx
pop dx
pop ax
ret
show endp
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;子程序结束
CODES ENDS
END START
;#######################################################代码段结束