汇编语言程序设计
实验内容:
编写程序,接收从键盘输入某班学生的学号、姓名、成绩,对学生的成绩进行排序,最后把学号、姓名、学生成绩、名次显示出来。
实验要求:
必须画流程图,流程图只画排序部分即可。
本程序要求涉及汇编语言的多重循环、子程序及宏,其中 成绩输入、计算学生名次、显示学生名次等都分别用子程序,也可用宏处理。
要求用菜单选择程序的各项功能。具体要求:
输入序号1:数据录入并输出(包括姓名、学号、成绩);
输入序号2:排序后的数据输出(包括姓名、学号、成绩、名次);
输入序号3:可以按学号查找某学生,并输出其成绩,选择修改或不改成绩。(可以选做)
注意:完成综合实验的最低要求是录入不定位数的成绩并排序,所有数据录入必须有合法性判断。如成绩输入,判断成绩是否为数值,是否在0~100之间。
;CLD 使DF=0
;STD 使DF=1
;串传送中,传送方向由方向标志位DF指出,
;若DF=0,传送时存储单元地址SI和DI自动加1or2
;若DF=1,SI和DI自动减量
程序设计
DATAS SEGMENT
;此处输入数据段代码
BUF0 DB '------0.MUNE------$'
BUF1 DB 0AH,0DH,'------1.INPUT-----$'
BUF2 DB 0AH,0DH,'------2.SORT------$'
BUF3 DB 0AH,0DH,'------3.PUT-------$'
senter db 0ah,0dh,'$'
select db 0ah,0dh,'INPUT YOUR ELECT:$'
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
MAIN PROC FAR
START:
MOV AX,DATAS
MOV DS,AX
;此处输入代码段代码
MOV ES,AX
CALL MUNE;调用菜单
MOV AH,4CH
INT 21H
MAIN ENDP
;子程序,菜单
MUNE PROC
CALL HHH
MOV AH,9
LEA DX,BUF0
INT 21H
LEA DX,BUF1
INT 21H
LEA DX,BUF2
INT 21H
LEA DX,BUF3
INT 21H
CALL HHH;回车换行
call elect;选择
RET
MUNE ENDP
;子程序,-----------回车换行---------------------
HHH proc
mov ah,9
lea dx,Senter;回车换行
int 21h
ret
HHH endp
;子程序,-----------选择---------------------
elect proc
mov ah,9
lea dx,select;选择
int 21h
MOV AH,1;输入一个选项
INT 21H
SUB AL,30H
.IF AL==1
;------1.INPUT-----
CALL INPUT
.ELSEIF AL==2
;------2.SORT-----
CALL SORT
.ELSEIF AL==0
;------0.MUNE-----
CALL MUNE
.ELSE
;------3.PUT-------
CALL PUT
.ENDIF
ret
elect endp
;子程序输入------1.INPUT-----
INPUT PROC
MOV AH,9
LEA DX,BUF1
INT 21H
RET
INPUT ENDP
;子程序排序-------2.SORT----------
SORT PROC
MOV AH,9
LEA DX,BUF2
INT 21H
RET
SORT ENDP
;子程序输出---------3.PUT---------
PUT PROC
MOV AH,9
LEA DX,BUF3
INT 21H
RET
PUT ENDP
CODES ENDS
END MAIN
END START
1.实现菜单输出与选择
以下代码满足题目要求:
以下代码满足题目要求:
include macor.lib
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;结构体class,用于存放学生信息
class struc
names db 20 dup (?)
ID db 20 dup (?)
score dw ?
class ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;定义数据段
DATAS SEGMENT
member class 50 dup(<>)
x dw 42
y dw 0
z dw 0
m db 0
BUF DB 20 dup (?)
show1 db "============================================================",13,10
db "Options:",13,10
db "0.mune",13,10
db "1.Input student informations(name,ID,score)",13,10
db "2.Output student informations(name,ID,score,ranking)",13,10
db "3.Find student informations(ID)",13,10
db "============================================================",13,10,"$"
select db 0ah,0dh,'INPUT YOUR ELECT:$'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
details1 db "name(eg:MasterShi):$"
details2 db "ID(eg:201407014212):$"
details3 db "score(0-100):$"
details4 db "name ID score",13,10,"$"
details5 db "name ID score ranking",13,10,"$"
error1 db 10,13,"Input error,elect must is 0~2,please input again:$"
scoreerror db 10,13,"The score must be 0~100..$"
nameerror db 10,13,"name must be A~Z or a~z..$"
iderror db 10,13,"ID must made by 0~9..$"
nobody db 10,13,"nobody! $"
amend db 10,13,"amend it?$"
blank db " $";十位数
blank1 db " $";百位数
blank2 db " $";个位数
temp1 db 20 dup(?)
temp2 db 20 dup(?)
result dw 0
wc dw 0
count dw 0
ranks db 0
hundred db '100$'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DATAS ENDS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;定义堆栈段
stacks segment
stacks ends
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;代码段
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
MAIN PROC FAR
START:
MOV AX,DATAS
mov ds,ax ;加载数据段
mov es,ax ;加载附加段
CALL MUNE;调用菜单
MOV AH,4CH
INT 21H
MAIN ENDP
;子程序====================菜单====================
MUNE PROC
LD
oustring show1
oustring select;选择
input;输入一个选项
sub al,30h
.IF AL==0
CALL MUNE
.ELSEIF AL==1
CALL INPUTinformation
.ELSEIF AL==2
CALL outputinformation
.ELSEIF AL==3
CALL findinformation
.ELSE
CALL error
.ENDIF
RET
MUNE ENDP
;子程序====================输入错误==============
error proc
ld
oustring error1;IDerror db "ID must made by 0~9..$"
call mune
ret
error endp
;子程序输入================1.INPUTinformation=================
INPUTinformation PROC
ld
call inputname
call inputID
call inputscore
call outputdata
call mune
RET
INPUTinformation ENDP
;============================
outputdata proc
ld
oustring details4
;details4 db "name ID score",13,10,"$"
mov cx,z
mov count,cx
mov bx,0
ccc:
;mov si,0
mov member[bx].names[16],'$'
oustring member[bx].names ;bx单元中的names显示完毕
mov member[bx].ID[16],'$'
oustring member[bx].ID ;bx单元中的ID显示完毕
cmp member[bx].score,10
jge abten;大于10跳到abten
mov dx,member[bx].score
add dl,30h
output dl
jmp ddd
abten:
cmp member[bx].score,100
jnz min;小于100跳到min
oustring hundred
jmp ddd
min:;大于10小于100输出
mov ax,member[bx].score
mov cl,10
div cl
mov cl,ah
add al,30h
output al
add CL,30h
output CL
ddd:
ld
add bx,x
dec count
cmp count,0
jnz ccc
ret
outputdata endp
;--------inputscore----------------------------------------
inputscore proc
oustring details3
mov si,0
mov bx,0
lp3:
input
mov m,al
.if m==0dh;输入回车跳到out3
jmp out3
.elseif m>=30h&&m<=39h;输入的字符在0-9之间
jmp correctscore
.else
jmp errorscore
.endif
correctscore:
sub al,30h
cbw ;扩展为字
xchg ax,bx
mov cl,10
imul cl
add bx,ax
jmp lp3
errorscore:
ld
oustring scoreerror
ld
mov bx,y
mov member[bx].score,0;score清零
call inputscore
out3:
cmp bx,100
jg errorscore
mov ax,bx
mov bx,y
mov member[bx].score,ax
mov ax,x
add y,ax
inc z
ret
inputscore endp
;==============================================
;-----------------------------------------------
inputID proc
oustring details2
mov si,-1
lp2:
inc si
input
mov m,al
.if m==0dh;回车跳出
jmp out2
.elseif m>=30h&&m<=39h;输入的字符在0-9之间
jmp correctID
.else
jmp errorID
.ENdIF
correctID:
mov bx,y
mov member[bx].ID[si],al;把录入的学号存入
jmp lp2
errorID:
ld
oustring iderror
ld
cc2:
dec si
cmp si,0
jl lp2
mov bx,y
mov member[bx].ID[si],0;ID清零
jmp cc2
out2:
ret
inputID endp
;=============================================
;------------------------------------------------
inputname proc
oustring details1
mov si,-1
lp1:
inc si
input
mov m,al
.if m==0dh;回车跳出
jmp out1
.elseif m>=41h&&m<=5ah;输入在A-Z之间
jmp correctname
.elseif m>=61h&&m<=7ah;输入在a-z之间
jmp correctname
.else
jmp errorname;输入错误
.endif
errorname:
ld
oustring nameerror
ld
cc1:;NAME清零
dec si
cmp si,0
jl lp1
mov bx,y
mov member[bx].names[si],0;NAME清零
jmp cc1
correctname:
mov bx,y
mov member[bx].names[si],al ;把录入的姓名的字母存入member.name中
;inc si
jmp lp1
out1:
ret
inputname endp
;子程序排序===============2.outputinformation==================
outputinformation PROC
ld
oustring details5
;details5 db "name ID score ranking",13,10,"$"
ld
cmp z,0
jz nobodys;没有学生信息
;比较思路,外层循环控制比较次数,内层循环控制被比较的元素
mov cx,z ;人数,行数,也是控制被比较次数的关键数
dec cx ;n个人比较n-1次
mov wc,cx ;外循环
ccompare:
mov cx,wc
mov result,cx ;内循环
mov bx,0
compare:
mov ax,member[bx].score
add bx,x
cmp ax,member[bx].score ;两个score比较
jl exchange ;如果前面比后面小,交换
dec result
cmp result,0
jg compare;内循环
dec wc
cmp wc,0
jg ccompare;外循环
jmp out5
exchange:
mov dx,member[bx].score;DX=22
sub bx,x
mov member[bx].score,dx;11被22覆盖,即替换掉
;把后面大的数给前面
add bx,x
mov member[bx].score,ax;22被11覆盖,即替换掉
;把前面小的数给后面
;names
lea si,member[bx].names;BBB的地址给SI
lea di,temp1 ;空temp1
mov cx,20
rep movsb ;把后面的串(BBB)送给temp1
sub bx,x
lea si,member[bx].names;AAA的地址给SI
lea di,temp2 ;空temp2
mov cx,20
rep movsb ;把前面的串(AAA)送给temp2
lea si,temp1 ;BBB的地址给SI
lea di,member[bx].names ;AAA的地址给DI
mov cx,20
rep movsb ;把temp1(BBB)送给前面的串(AAA)
add bx,x
lea si,temp2 ;AAA的地址给SI
lea di,member[bx].names ;BBB的地址给DI
mov cx,20
rep movsb ;把temp2(AAA)送给后面的串(BBB)
;ID
lea si,member[bx].ID
lea di,temp1
mov cx,20
rep movsb ;把后面的串送给temp1
sub bx,x
lea si,member[bx].ID
lea di,temp2
mov cx,20
rep movsb ;把前面的串送给temp2
lea si,temp1
lea di,member[bx].ID
mov cx,20
rep movsb ;把temp1送给前面的串
add bx,x
lea si,temp2
lea di,member[bx].ID
mov cx,20
rep movsb ;把temp2送给后面的串
dec result
cmp result,0
jg compare;内循环
dec wc
cmp wc,0
jg ccompare;外循环
jmp out5
nobodys:
oustring nobody
ret
out5:
call displayrank;排名
RET
outputinformation ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
displayrank proc
ld
oustring details5
mov cx,z ;行数
mov count,cx
mov bx,0
ccc:
mov member[bx].names[16],'$'
oustring member[bx].names ;bx单元中的names显示完毕
mov member[bx].ID[16],'$'
oustring member[bx].ID ;bx单元中的ID显示完毕
cmp member[bx].score,10
jge abten;大于10跳到abten
mov dx,member[bx].score
add dl,30h
output dl
jmp ddd
abten:
cmp member[bx].score,100
jnz min;小于100跳到min
oustring hundred
jmp ddd
min:;大于10小于100输出
mov ax,member[bx].score
mov cl,10
div cl
mov cl,ah
add al,30h
output al
add CL,30h
output CL
ddd: ;score显示完毕,准备显示ranking
inc ranks
cmp member[bx].score,100
jz bbb1
cmp member[bx].score,10
jl bbb2
oustring blank;十位数
jmp xxx
bbb1:
oustring blank1;百位数
jmp xxx
bbb2:
oustring blank2;个位数
xxx:
mov dl,ranks
add dl,30h
output dl
ld
add bx,x
dec count
cmp count,0
jg ccc
mov ranks,0
call mune
ret
displayrank endp
;=================================================================
;;;;;;;;;;;;;;;;;;;;;;;;;;;findinformation;;;;;;;;;;;;;;;;;;;;;;;;
findinformation proc
LD
CALL INPUTBUF;输入要查找的学号
;mov y,bx ;保护BX的值
mov bx,0
let2:
mov member[bx].ID[16],'$'
;oustring member[bx].ID
lea si,member[bx].id
;lea si,temp1
lea di,buf
cld
mov cx,20
repe cmpsb
jz let1 ;相等转let1
add bx,x
jmp let3 ;不相等转let3
let3:
cmp bx,z
jg nobodys
jmp let2
nobodys:
oustring nobody
call outputdata
call mune
ret
let1: ;相等
;;;;;;;;;;;;;;;;;;;;;输出该学号的成绩
cmp member[bx].score,10
jge abten;大于10跳到abten
mov dx,member[bx].score
add dl,30h
output dl
jmp ddd
abten:
cmp member[bx].score,100
jnz min;小于100跳到min
oustring hundred
jmp ddd
min:;大于10小于100输出
mov ax,member[bx].score
mov cl,10
div cl
mov cl,ah
add al,30h
output al
add CL,30h
output CL
ddd: ;结束成绩输出
ld
oustring amend;询问是否修改
input
mov m,al
.if m==4eh||m==6eh ;al=N或者al=n
jmp nnn
.else ;al=Y或者al=y
jmp yyy
.endif
YYY:
ld
oustring details3
mov y,bx;保护bx
mov member[bx].score,0;score清零
mov bx,0;为不定位输入做准备
lp3:
input
mov m,al
.if m==0dh;输入回车跳到out3
jmp out3
.elseif m>=30h&&m<=39h;输入的字符在0-9之间
jmp correctscore
.else
jmp errorscore
.endif
correctscore:
sub al,30h
cbw ;扩展为字
xchg ax,bx
mov cl,10
imul cl
add bx,ax
jmp lp3
errorscore:
ld
oustring scoreerror
ld
mov bx,y ;回送BX的值
mov member[bx].score,0;score清零
call inputscore
out3:
cmp bx,100
jg errorscore
mov ax,bx
mov bx,y ;回送BX的值
mov member[bx].score,ax ;存入新成绩
NNN: ;不修改跳出
call outputdata
call mune
ret
findinformation endp
;===============================
INPUTBUF PROC
ld
oustring details2
mov si,-1
lp2:
input
mov m,al
.if m==0dh;回车跳出
jmp out2
.elseif m>=30h&&m<=39h;输入的字符在0-9之间
jmp correctID
.else
jmp errorID
.ENdIF
correctID:
inc si
mov BUF[si],al;把录入的学号存入
jmp lp2
errorID:
ld
oustring iderror
ld
cc2:
dec si
cmp si,0
jl lp2
mov BUF[si],0;ID清零
jmp cc2
out2:
mov buf[16],'$'
ret
inputBUF endp
CODES ENDS
END MAIN
END START