《 汇 编 语 言》课程综合性实验报告
实验题目
一、实验目的
显示学生名次表
进行汇编语言程序设计应用的综合性训练。综合运用汇编语言循环程序、子程序、宏指令编
程方法,提高汇编语言程序设计能力的应用水平。
二、设备与环境
PC 兼容机、Windows 操作系统、汇编程序 masm for windows 2012
三、实验内容
编制一程序,要求接收从键盘输入的一个班的学生的学号、姓名、成绩,对学生的成绩进
行排序,最后把学号、姓名、学生成绩、名次显示出来。
实验要求:
1.必须画流程图。
2.本程序涉及汇编语言的多重循环、子程序及宏,其中 成绩输入、计算学生名次、显示学
生名次都分别用子程序,也可用宏处理。
3.要求用菜单选择。具体要求:
输入 1 是数据录入并输出(包括姓名、学号、成绩);
输入 2 是排序后的数据输出(包括姓名、学号、成绩、名次);
输入 3 是可以按学号查找某学生,并输出其成绩,选择修改或不改成绩。
四、实验结果及分析
首先说明的是本程序中是成绩为 100 进制的系统。
1. 已完成的功能:
可以用菜单选择需要使用的功能,输入 1 是数据录入并输出(包括姓名、学号、成绩);输
入 2 是排序后的数据输出(包括姓名、学号、成绩、名次);输入 3 是可以按学号查找某学生,
并输出其成绩,选择修改或不改成绩,输出更改后的学生库数据。
2. 实现的方式、遇到的问题和解决办法、流程图和关键代码解释。
图一:主程序流程图:
华北科技学院综合性实验报告
是
判断是否继续
否
是
是
数 据 录 入
并输出
排 序 后 的
数据输出
按 学 号 查 找
某学生
主程序开始
菜单输出;
功能号选择
判断是否输入
“1”
否
判断是否输入
“2”
否
判断是否输入
“3”
结束程序
2.1 数据录入并输出(包括姓名、学号、成绩)。
首先,我的数据单元是定长度的,即每个姓名、成绩、学号在存储单元的长度是固定的。之
前做到一半发现不定长的数据难以读取,再看报告的要求,发现自己的思路不对,以为要重新做,
后来发现可以在输入的数据之后自动加空格,并且固定的话,便于读取,使用 inbuf db 12 dup('
'),'$' 定义缓冲区既可,只要包 inbuf 里的数据全都存储到数据单元既可固定。
对于数据的录入,我是用 1 号功能对单个字符输入,输入一个字符存储一个字符到 inbuf 缓
冲区(定义了一个长度为 13 的)中,再把 inbuf 缓冲区的数据全部转移到 outname 中(包括$),
用 di 标记每个姓名数据的起始单元。因此在录入功能中我非常注意给 di 的保护,用 push 和 pop
方法。姓名、成绩、学号都是一样的输入存储方法,但是在成绩中,我对位数(即成绩输入长度)
第 1 页
华北科技学院综合性实验报告
做了保存,供之后用。注意对缓存区的清零。
GETCHAR 子程序的部分代码
lp3:
mov ah,1
int 21h
;使用 1 号功能输入
cmp al,0dh ;回车判断结束输入
je lp4
mov INBUF[bx],al;保存入键
inc bx
jmp lp3
对于数据的输出,用九号功能实现对串的输出,依次输出姓名、学号和成绩,循环依次,di
指针后移 13 个,用 loop 循环既可。
此时,为了实现之后的排序,我取出 outgrate 中的各个成绩进行转换,以 10 进制的方式存
储到 score1 中。其中,因为成绩最大是 100,所以首先考虑 3 位数,我判断,成绩的第三位是否
为“0”,对于成绩来说,有数字的话只能是 0,是零就在 score 相应的单元直接给值 100;然后
考虑 1 位数,如果成绩的第二位是否为“ ”(即空格),我之前转存的 inbuf 中的数据,不仅包
括我的输入字符,还有空格填满,一并存入到 outgrade 中,因此可以用空格判断。
Change 的关键代码:
mov cx,a
w1:cmp outgrade[si+2],'0'
jz w2
cmp outgrade[si+1],' '
jnz w3
mov al,outgrade[si]
mov score1[bx],al
jmp exit22
w2: mov score1[bx],100
jmp exit22
w3:mov al,OUTgrade[si];计算两位数
sub al,30h
sub outgrade[si]+1,30h;输入的成绩改了,注意!
imul s;十位数*10
add al,OUTgrade[si]+1
mov score1[bx],al
add outgrade[si]+1,30h
exit22:
add si,13
inc bx
mov mingci[di],bl;记录位置!!!!!!
inc di
loop w1
图一为录入程序流程图
图二为成绩排序子程序的流程图:
第 2 页
inc si
是
华北科技学院综合性实验报告
子程序开始
开始
mov cx,a;
(a 为总人数)
push cx
人数减一次赋
给 cx
push cx
call OUT_NAME
score[si]>score[si]+1
call OUT_NAME
call OUT_NAME
pop cx
cx=0
是
否
call shuchu
否
结束
图 1
否
成绩交换
名次交换
pop cx
dec cx
cx=0
是
结束
图 2
2.2 排序后的数据输出(包括姓名、学号、成绩、名次)。
对于排序准备工作,我在之前的 score1 中,特别添加了存储的顺序,即第一次输入 100 时,
把 100 在 outgrade 的位置 0 存储到 mingci 的第一个单元;第二次输入 50 时,把 50 在 outgrade
的位置 1 存储到 mingci 的第一个单元。
排序的时候,我用 loop 循环,采用的是冒泡排序法。图二为冒泡法的流程图。
排序的关键代码:
loop1:;外循环
push cx ;一定要对cx保护一下,内循环会影响cx的值
第 3 页
mov si,0;从score1的第一个单元开始循环
loop2: ;内循环
华北科技学院综合性实验报告
mov al,score1[si]
cmp al,score1[si]+1
jge next; 降序
xchg al,score1[si]+1;交换
mov score1[si],al
mov al,0;名次不用比较,直接随成绩一起交换
mov al,mingci[si]
xchg al,mingci[si]+1
mov mingci[si],al
next:inc si;指针si下移
loop loop2
pop cx;恢复外循环
loop loop1
对于排序后信息的输出,我是取出 mingci 中的值,乘以数据的固定的位数(即是对于要取出
数据的起始值),但是 outname、outsno、outgrade 的首地址指向 dx 时,用“add dx,ax”取值,
用九号功能输出,注意要在输入“mov ah,9”之前完成相加过程,不然会影响 dx 的值,影响输
出。2018 年 12 月 30 日 21:24:19
关键代码:
mov ax,0
mov al,mingci[di]
dec al
mov bl,13
imul bl
lea dx,outname
add dx,ax
mov ah,9
int 21h
2.3 可以按学号查找某学生,并输出其成绩,选择修改或不改成绩。
对于用学号的查找学生,我首先用数据输入的方式输入,存在缓冲区 inbuf 中,并统计输入
学号的长度 cz,用串指令 cmpsb 对 inbuf 和 outsno 进行比较,但是每次的 outsno 取位移量是不
同的,每次加 13 个单元,进行下一个单元的比较。
关键代码:
lea si,outsno[bx]
lea di,inbuf
cld
mov cx,13
repe cmpsb
jz z55
add bx,13
因为其他地方没有使用 bx 单元,成绩的输出就非常简单,直接把 outgrade[bx]地址给 dx,
第 4 页
用 9 号功能输出既可。
华北科技学院综合性实验报告
对于选择修改或不改成绩成绩,我想到了用之前输入的子程序 GETCHAR 就可以了。可是,我
出现了一些问题,修改成绩之后,用输出所有人成绩验证是否输入数据时发现,下一个单元的姓
名无法输出,看了一下代码发现,我是用回车判断结束的,这样势必会一下下一行数据的输出。
后来改为用循环 loop 输入的方法,但是发现,是有修改,但是如果输入的是两位数,之前的数
据是三位数的话,最后一位还是存在着没有覆盖掉,于是我在输入的时候,用空格判断结束,循
环 3 次,这样就可以输出了,当然了还是有点缺陷的,输入 100 的时候不需要空格直接会输出所
有人的数据。
2.4 综合
对于本次编写的程序,为了实现菜单的循环,即菜单一二三是可以实现循环跳转,我一开始
出现菜单三修改成绩后时出现乱码的情况,这个问题我查程序的时候发现,我一开始 push 的寄
存器都是默认为空的,第二次 push 进去的时候就不是为空了,之后我的 push 工作都是枉费的,
于是我就在一开始就给结果会影响结果的值清零之后在 push,程序就好了。在一番反复选择、修
改、排序、输出之后,已经做好了,目前为止没有出错。
程序运行截图如下:
输出菜单,选择“1”号功能,进行数据的录入。
第 5 页
华北科技学院综合性实验报告
录入成功后,系统会自动输出下面结果。
选择菜单 2,输出排序的顺序
第 6 页
华北科技学院综合性实验报告
选择菜单 3,按要求进行输入,显示该学生的成绩,在按要求进行。
截图如下:给学号 20132222 修改成绩为 99.
打空格之后,输出修改后的结果:学生 20132222 成绩已修改为 99
第 7 页