汇编语言综合实验学生成绩排序单链表实现.docx

上传人:b****8 文档编号:10066908 上传时间:2023-05-23 格式:DOCX 页数:22 大小:178.98KB
下载 相关 举报
汇编语言综合实验学生成绩排序单链表实现.docx_第1页
第1页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第2页
第2页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第3页
第3页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第4页
第4页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第5页
第5页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第6页
第6页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第7页
第7页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第8页
第8页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第9页
第9页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第10页
第10页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第11页
第11页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第12页
第12页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第13页
第13页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第14页
第14页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第15页
第15页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第16页
第16页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第17页
第17页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第18页
第18页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第19页
第19页 / 共22页
汇编语言综合实验学生成绩排序单链表实现.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

汇编语言综合实验学生成绩排序单链表实现.docx

《汇编语言综合实验学生成绩排序单链表实现.docx》由会员分享,可在线阅读,更多相关《汇编语言综合实验学生成绩排序单链表实现.docx(22页珍藏版)》请在冰点文库上搜索。

汇编语言综合实验学生成绩排序单链表实现.docx

汇编语言综合实验学生成绩排序单链表实现

《汇编语言》课程综合性实验报告

实验题目

显示学生名次表

一、实验目的

通过显示学生成绩名次表,进行汇编语言程序设计应用的综合性训练。

综合运用汇编语言循环程序、子程序、宏指令编程方法,提高汇编语言程序设计能力的应用水平。

二、设备与环境

PC兼容机、Windows操作系统、汇编程序masmforwindows2012。

三、实验内容

1.实验内容:

编制一程序,要求接收从键盘输入的一个班的学生的学号、姓名、成绩,对学生的成绩进行排序,再按学号顺序和学生名次顺序分别把学生成绩显示出来。

2.实验要求:

①必须画程序流程图。

②本程序要求要有多重循环和子程序及宏,其中成绩输入、计算学生名次、显示学生名次都分别用子程序,也可用宏处理。

③要求用菜单选择,输入1时按学号顺序输出成绩(包括姓名、学号、成绩、名次),输入2时按成绩排名顺序输出成绩(包括姓名、学号、成绩、名次)。

四、实验结果及分析

1.主界面的设计与实现:

(1)程序分为两个菜单:

①一级菜单:

完成学生成绩的录入或从本地文件中载入学生成绩信息。

(图1-1)用户输入对应选项1、2、3或L、C、E,分别执行相应的功能。

输入1(或L):

表示从文件中读取学生成绩信息;

输入2(或C):

表示重新录入学生成绩信息,并保存到文件中;

输入3(或E):

表示退出程序。

②二级菜单:

完成对学生成绩信息的排序,并输出排序后结果。

(图1-2)

输入1:

完成按学号排序(升序)并输出排序后结果;

输入2:

完成按总分排序(降序)并输出排序后结果;

输入3:

返回一级菜单。

图1-1程序主界面:

 

图1-2程序二级菜单界面:

2.排序功能的实现:

图1-2输入学生成绩界面:

图1-4按总分排序输出学生成绩信息:

3.设计思路:

(1)数据定义:

一个数据元素(一个学生的数据项)应该为一个结构类型,定义如下:

STUDENTSTRUC;定义学生结构体

LINKDW0;单链表指针,指向下一个节点偏移地址

IDDB'000';学号

NAMESDB'$$$$$$$$';姓名

CSCOREDB?

;语文成绩

MSCOREDB?

;数学成绩

SUMDB?

;总分

STUDENTENDS

其中,LINK字段为链指针,指向数据元素的后续地址,它占用一个字,其初值为0;ID字段为3个字节,存放学号,为了输入输出方便,学号以3位十进制数字的字符存放;NAMES字段为8个字节,存放姓名,为了方便输出,预设8个‘$’符号;CSCORE字段、MSCORE字段和SUM字段分别为学生的语文成绩、数学成绩、总成绩,由于这3个字段的值不超过200,分别以一个字节的二进制存放即可。

每一个学生的数据信息为结构S这样一个数据元素。

则10个学生需要分配10个这样的数据元素的存储单元。

用上面的结构名STUDENT作为伪指令定义学生数组如下:

S_ARRAYSTUDENT10DUP(<>);预设学生人数为10

S_ARRAY是一个结构类型的数组,它包括10个元素,每一个元素为一个STUDENT类型的结构。

在建立链表的过程中,会用数组元素的首地址装填LINK字段,为了避免冲突,数组元素的首地址不能为0和1,因此,在数据段定义中定义S_ARRAY数组之前,用DW分配了一个字,使数组S_ARRAY的第一个元素的位移量不为0,也不为1。

(2)方法和步骤:

这个程序主要包括3个部分:

输入数据、按学生的总成绩由高到低(降序)建立链表和按学生名次输出学生信息。

①输入数据。

从数组的第一个元素开始,顺序填装数据元素,因此设置循环将S_ARRAY数组第一个元素的位移量送至BX,每一次循环,BX加上TYPES_ARRAY(值为16),使BX指向S_ARRAY数组中下一个元素的起始地址。

装填每个元素的各字段值:

输入学号存放到S_ARRAY数组元素的ID字段;输入姓名、语文成绩、数学成绩并分别存放到数组元素的NAMES字段、CSCORE字段和MSCORE字段;将CSCORE字段和MSCORE字段的值相加得到总成绩送入SUM字段。

②按学生的总成绩由高到低进行排序建立链表。

这一部分任务是按学生总成绩由高到低进行排序。

采用单链表方式,给数据元素的链指针LINK字段装填数据,使LINK字段指向它的后继数据元素。

步骤如下:

Ⅰ.初始时,数组元素的每个LINK字段值为0,表示数组元素没有被选中。

扫描数组元素的SUM字段,从中找到第一个最大的数,将这个数组元素设置为链表的头,保存这个数组元素的位移量,并将其LINK字段设置为1,标记这个数组元素已被选中但尚未装填链指针。

Ⅱ.扫描整个数组,从链指针字段为0的数组元素中寻找SUM字段最大的数组元素,将这个数组元素的位移量填至上一个最大元素的LINK字段,并将1送至这个数组元素的LINK字段。

Ⅲ.重复执行步骤Ⅱ,最后剩下一个链指针字段值为1的数组元素,该元素是链表的链尾。

③按名次(总成绩由高到低的顺序)输出学生信息,也就是按链表中元素的顺序访问其数据元素。

步骤如下:

Ⅰ.将链表的头元素的位移量送到BX寄存器。

Ⅱ.输出BX指向的数据元素的信息,即学号、姓名、语文成绩、数学成绩和总成绩,输出回车换行。

判断[BX].LINK字段的值是否为1,为1则结束程序,否则将该元素LINK字段的内容送入BX中,重复步骤Ⅱ。

4.流程图与关键代码分析:

①按学生总成绩排序(降序)流程图,同时建立单链表:

②按名次由高到低输出学生成绩信息子程序(即单链表方式顺序输出):

5.总结与体会:

(1)程序主要完成功能:

①从键盘输入学生成绩信息,依次将学生的学号、姓名、语文成绩、数学成绩、总成绩(经过计算后),存放在对应数组元素的字段中。

②按照总成绩从高到低排序,即完成单链表的建立,将单链表的头指针保存在DX寄存器中,在输出时从头指针开始遍历单链表。

③按照学生总成绩的名次顺序(由高到低)输出学生成绩信息,即对②所建立的单链表的遍历,在初始时需要将单链表头指针(DX寄存器中存放)赋值给BX,以便完成遍历输出。

(2)程序的实现:

①主要采用了结构数组,因为每一个学生数据项都具有相同的结构,因此先定义一个STUDENT类型的结构体,使用该结构体名作为伪操作指令定义n个相同的结构体类型的数组元素。

在每一个数组元素中都包含一个LINK字段,初始值为0。

②建立单链表,即完成对学生成绩信息的降序排列。

首先从所有数组元素中找出总成绩最大的一项,将该数组元素作为单链表的头指针,保存在DX中,同时将LINK字段赋值为1;

其次,从LINK字段为0的数组元素中找到总成绩最大的一项,将该数组元素的偏移地址作为前一节点的LINK字段值,同时将该节点的LINK字段值置为1;

重复上述步骤直到该结构体类型数组中的最后一个节点LINK字段置为1,该节点即为单链表的链尾。

③遍历单链表,即对学生成绩信息按总成绩由高到低输出。

首先将单链表的头指针赋值给BX,依次循环COUNT(学生人数)次输出每一个数组元素的值,每次输出结束后,将BX的值加上TYPES_ARRAY(即加16字节),BX指向下一个数组元素的首地址。

其次在输出每一个数组元素后,即循环的过程中必须同时满足两个条件:

计数器CX!

=0且[BX].LINK!

=1,若有任意一个条件不满足则跳出循环。

使用LOOPNZ指令即可实现。

④对于将学生成绩信息保存到文件,以及从文件中读取学生成绩信息并输出,关于文件的打开、读取、写入、关闭,这一块相关功能并没有实现。

⑤程序纠错功能较差,当用户输入错误后,没办法实现退格删除,重新输入,有待改进。

⑥由于学生的姓名不定长,导致输出时对齐存在一定困难。

⑦程序还可以继续优化,结合子程序与宏各自的优点,宏的调用速度块,可以用实元代替哑元的方式完成调用不同的子程序,以及灵活的传值,而子程序应该做到可以被多次调用,写的更为灵活、复用性高。

(3)收获和体会:

通过本次综合实验不仅提高了汇编语言程序设计的能力,也对高级汇编技术有了初步的认识与了解,如子程序与宏的配合使用。

同时对于程序的算法,才是程序的核心,是程序设计的重点,根据对程序中数据的分析,采取不同的数据结构,结合优良的算法,可以大大提高程序的效率。

对自己在以后的学习中更应该重视基础、把握重点,编程语言是工具,而算法、结构才是核心。

只有结合良好的思想指导,熟悉利用工具才能做出好的软件。

 

源代码:

CRLFMACRO;回车换行宏定义

MOVDL,0DH

MOVAH,02H

INT21H

MOVDL,0AH

INT21H

ENDM

BLANKMACRONUM;空格宏定义

MOVCX,NUM

CALLBLANK_PROC

ENDM

SHOWMACROSTRING;显示字符串宏定义

LEADX,STRING

MOVAH,09H

INT21H

ENDM

STUDENTSTRUC;定义学生结构体

LINKDW0;指针,指向下一个节点

IDDB'000';学号

NAMESDB'$$$$$$$$';姓名

CSCOREDB?

;语文成绩

MSCOREDB?

;数学成绩

SUMDB?

;总分

STUDENTENDS

DATASGSEGMENT

DW?

;避免数组元素和LINK字段冲突

S_ARRAYSTUDENT4DUP(<>);预设学生人数

NUMBERDW0;键盘输入学生人数

COUNTEQULENGTHS_ARRAY

;COUNTEQUNUMBER;定义学生人数个数COUNT

;==================菜单=======================

MENU1DB0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH

DB"------------------MENU(LoadORCreate)---------------------",0DH,0AH,0D,0AH

DB"1.Loadthestudentinformationfromanexistingfile(L)",0DH,0AH,0D,0AH

DB"2.Createanewfileandwritethestudentinformation(C)",0DH,0AH,0D,0AH

DB"3.Exitthestudentachievementmanagementsystem(E)",0DH,0AH,0D,0AH

DB"-----------------------------------------------------------",0DH,0AH,0D,0AH

DB"PleaseInputYourChoice:

",'$'

MENU2DB0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH,0DH,0AH

DB"------------MENU(Display)--------------",0DH,0AH,0DH,0AH

DB"1.SortbystudentID",0DH,0AH,0DH,0AH

DB"2.Sortbyscores",0DH,0AH,0DH,0AH

DB"3.Backtopreviousmenu",0DH,0AH,0DH,0AH

DB"---------------------------------------",0DH,0AH,0DH,0AH

DB"Pleaseinputyourchioce:

",'$'

PRESS_KEYdb0dh,0ah,'Pleasepressanykeytocontinue...','$'

INPUT_NUMBERdb'Pleaseinputthenumberofstudents:

','$'

INPUT_INFOdb0Dh,0Ah,'IDNAMEChineseMath',0Dh,0Ah,0Dh,0Ah,'$'

OUTPUT_INFOdb'IDNAMEChineseMathSUM',0dh,0ah,0Dh,0Ah,'$'

;================菜单定义结束===============

DATASGENDS

STACKSGSEGMENT

DW200DUP(?

STACKSGENDS

CODESGSEGMENT

ASSUMECS:

CODESG,DS:

DATASG,SS:

STACKSG

START:

MOVAX,DATASG

MOVDS,AX

MOVAX,STACKSG

MOVSS,AX

MOVSP,200

;=============输出菜单1==================

MAIN_MENU1:

MOVAX,0003H;清屏

INT10H

SHOWMENU1;输出菜单1

MOVAH,01H

INT21H

XORAH,AH

CMPAX,'L'

;JZ_LODEFILE;暂时不做处理

CMPAX,'C'

JZCALL_INPUT

CMPAX,'E'

JZENDPROC

CMPAX,'1'

;JZ_LODEFILE;暂时不做处理

CMPAX,'2'

JZCALL_INPUT

CMPAX,'3'

JZENDPROC

JMPMAIN_MENU1

;=============输出菜单2=================

MAIN_MENU2:

MOVAX,0003H;清屏

INT10H

SHOWMENU2;输出菜单2

MOVAH,01H

INT21H

XORAH,AH

CMPAX,'1'

;JZCALL_OUTPUT1;学号排序暂时不做处理

CMPAX,'2'

JZCALL_OUTPUT2;按总分排序

CMPAX,'3'

JZMAIN_MENU1

JMPMAIN_MENU2

;输入3位学号、姓名、语文、数学成绩,并计算总成绩,其中输入姓名、成绩以空格结束

CALL_INPUT:

MOVAX,0003H;清屏

INT10H

SHOWINPUT_NUMBER

MOVAH,1

INT21H

SUBAL,30H

XORAH,AH

MOVNUMBER,AX

CRLF

SHOWINPUT_INFO

CALLINPUT

JMPMAIN_MENU2

;按学号由小到大进行输出(先进行按学号由小到大排序)

CALL_OUTPUT1:

;按总分由大到小进行输出(先进行按总分由大到小排序)

CALL_OUTPUT2:

MOVAX,0003H;清屏

INT10H

SHOWOUTPUT_INFO

CALLSORT_SCORE

CALLOUTPUT

SHOWPRESS_KEY

MOVAH,01H

INT21H

JMPMAIN_MENU2

ENDPROC:

MOVAH,4CH

INT21H

;===============输入学生成绩信息子程序===============

INPUTPROCNEAR

PUSHAX

PUSHBX

PUSHCX

PUSHDX

PUSHDI

MOVBX,OFFSETS_ARRAY

MOVCX,COUNT

LOOP11:

PUSHCX

MOVDI,00H

MOVCX,03H

LOOP12:

MOVAH,01H

INT21H

MOV[BX].ID[DI],AL;输入学号

INCDI

LOOPLOOP12

BLANK03H

MOVDI,00H

MOVCX,06H

LOOP13:

MOVAH,01H

INT21H

CMPAL,''

JZNEXT

MOV[BX].NAMES[DI],AL;输入姓名

INCDI

LOOPLOOP13

NEXT:

BLANK04H

CALLINPUTGRADE

MOV[BX].CSCORE,DH

BLANK08H

CALLINPUTGRADE

MOV[BX].MSCORE,DH

ADDDH,[BX].CSCORE;计算总分

MOV[BX].SUM,DH

CRLF

ADDBX,TYPES_ARRAY;地址增加一个结构的大小

POPCX

LOOPLOOP11

POPDI

POPDX

POPCX

POPBX

POPAX

RET

INPUTENDP

;================按总分排序子程序2,由高到低===================

SORT_SCOREPROCNEAR

PUSHAX

PUSHBX

PUSHCX

PUSHSI

PUSHDI

MOVCX,COUNT

LOOP21:

PUSHCX

MOVCX,COUNT

MOVBX,OFFSETS_ARRAY

MOVAL,0

LOOP22:

CMP[BX].LINK,0

JNZL21

CMPAL,[BX].SUM

JAEL21

MOVAL,[BX].SUM

MOVDI,BX;将总分最高的学生地址保存在DI中

L21:

ADDBX,TYPES_ARRAY

LOOPLOOP22

POPCX

CMPCX,LENGTHS_ARRAY

JNEL22

MOVDX,DI;总分较高的学生的地址保存在DX中

JMPL23

L22:

MOV[SI].LINK,DI

L23:

MOVSI,DI

MOV[SI].LINK,1;表明该节点已经比较过

LOOPLOOP21

POPDI

POPSI

POPCX

POPBX

POPAX

RET

SORT_SCOREENDP

;===============输出子程序,按单链表方式=================

OUTPUTPROCNEAR;DX中存放头指针,将头指针赋值BX

PUSHAX

PUSHBX

PUSHCX

PUSHSI

MOVBX,DX

MOVCX,COUNT

LOOP31:

PUSHCX

MOVSI,0

MOVCX,3

LOOP32:

MOVDL,[BX].ID[SI];输出学号

MOVAH,02H

INT21H

INCSI

LOOPLOOP32

BLANK03H

MOVSI,0

NEXT1:

MOVAH,02H

MOVDL,[BX].NAMES[SI];输出姓名

CMPDL,'$'

JZNEXT2

INT21H

INCSI

JMPNEXT1

NEXT2:

BLANK04H

MOVDH,[BX].CSCORE

CALLPRINTGRADE;输出语文成绩

BLANK08H

MOVDH,[BX].MSCORE

CALLPRINTGRADE;输出数学成绩

BLANK05H

MOVDH,[BX].SUM

CALLPRINTGRADE;输出总成绩

CRLF

CMP[BX].LINK,1;指针为1表明为链表最后一个节点,跳出循环

MOVAX,[BX].LINK

MOVBX,AX

POPCX

LOOPNZLOOP31

POPSI

POPCX

POPBX

POPAX

RET

OUTPUTENDP

;===================输出空格子程序===================

BLANK_PROCPROCNEAR

LP1:

MOVDL,20H

MOVAH,02H

INT21H

LOOPLP1

RET

BLANK_PROCENDP

;=============输入成绩,将十进制转换为二进制=========

INPUTGRADEPROCNEAR

PUSHCX

PUSHBX

MOVCX,4

MOVDH,0

LOOP41:

MOVAH,01H

INT21H

CMPAL,''

JELP41

SUBAL,30H

MOVBH,AL

MOVBL,10

MOVAL,DH

MULBL

ADDAL,BH

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 自然科学 > 物理

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2