求汇编语言程序 傅德胜 答案1
发布网友
发布时间:2024-02-24 08:05
我来回答
共1个回答
热心网友
时间:2024-07-22 10:31
;本程序通过编译,运行正确
CodeSegment
AssumeCS:Code,DS:Code
CRequ000DH
LFequ000AH
KBBackequ0008H
;-------------------------------------
;功能:显示指定地址(Str_Addr)的字符串
;入口:
;Str_Addr=字符串地址(要求在数据段)
;用法:OutputStr_Addr
;用法举例:OutputPromptStr
OutputMACROStr_Addr
leadx,Str_Addr
movah,9
int21h
EndM
;-------------------------------------
;功能:输出一个字符
;入口:dl=要显示的字符
Output_ChrprocNear
pushax
movah,02h
int21h
popax
ret
Output_Chrendp
;-------------------------------------
;功能:输出回车换行
Output_CTLFprocNear
pushax
pushdx
movah,02h
movdl,0dh
int21h
movdl,0ah
int21h
popdx
popax
ret
Output_CTLFendp
;-------------------------------------
;功能:取光标位置
;入口:无
;出口:DH=行号,DL=列号
GetCursorProcNear
PUSHAX
PUSHBX
PUSHCX
XORBX,BX
MOVAH,3
INT10H
MOVCursor_Row,DH
MOVCursor_Col,DL
POPCX
POPBX
POPAX
RET
Cursor_RowDB?
Cursor_ColDB?
GetCursorEndP
;-------------------------------------
;功能:置光标位置
;入口:Cursor_Row=行坐标;Cursor_Col:列坐标)
SetCursorProcNear
PUSHCX
PUSHBX
PUSHAX
MOVDH,Cursor_Row
MOVDL,Cursor_Col
XORBX,BX
MOVAH,2
INT10H
POPAX
POPBX
POPCX
RET
SetCursorEndP
;-------------------------------------
;功能:键盘输入一个指定位数的十进制数字,将其转换成二进制数并保存在指定的内存单元。
;由于限定最大数据类型为字,所以,数字位数最多:5,最大无符号数:65536
;约定:直接回车,视为数字0
;入口:@@Digits=数字位数;di=保存输入的数字首地址
;@@Type_Data=保存的数据类型,B=字节类型,W=字类型。
;出口:转换后的二进制数保存在di所指的单元
Input_DigitProcNear
pushdx
pushcx
pushbx
pushdi
leadi,@@Save_Tmp
pushdi
cld
movcl,@@Digits
xorch,ch
pushcx
@@Input:callGetCursor;取光标位置
movah,1;从键盘接受一个字符
int21h
cmpal,CR;若键入的是回车,已经键入的数字不足N位
jz@@ASC_Dec;转去处理已经键入的数字
cmpal,KBBack
jz@@KB_Back;若是回空键,重新输入
cmpal,'0'
jb@@KBBack;若低于数字'0',重新输入
cmpal,'9'
ja@@KBBack;若低于数字'9',重新输入
jmp@@Save_Dig
@@KB_Back:decCursor_Col
inccx
decdi
@@KBBack:callSetCursor;置光标位置
jmp@@Input
@@Save_Dig:andal,0fh;转换成二进制数
stosb;保存
loop@@Input;接受下一个数字
@@ASC_Dec:movax,cx
popcx
popsi
subcx,ax;实际输入的数字位数
xorbp,bp
xordx,dx
xorax,ax
jcxz@@Save_Ret;若直接回车,没有输入任何数字,按输入'0'处理
deccx;实际输入的数字位数减1,准备把输入的这一串数字转换成二进制数
jcxz@@One_Digit;若输入的数字只有一位,转去直接保存这个二进制数
movbx,10
@@Mul_Ten:lodsb
cbw
addax,bp
mulbx
movbp,ax
loop@@Mul_Ten
@@One_Digit:lodsb
cbw
addax,bp
@@Save_Ret:popdi
cmp@@Type_Data,'B';字节类型?
jz$+5
stosw
jmp$+3
stosb
popbx
popcx
popdx
ret
@@Digitsdb?;十进制数字位数
@@Type_Datadb'B';保存的数据类型。B=字节类型,W=字类型
@@Save_Tmpdb16dup(?)
Input_DigitEndP
;-------------------------------------
;功能:把AX中的二进制无符号数转换成显式的十进制ASCII码,并送显示屏显示
;入口:AX=二进制数
;出口:在当前光标位置显示转换后的ASCII码数字
Dec_ASCIIProcNear
pushdx
pushbx
pushdi
movbx,10
leadi,@@Temp_Save[6]
movbyteptr[di],'$'
decdi
@@Divide:xordx,dx
divbx
ordl,30h
mov[di],dl
decdi
testax,0ffffh
jnz@@Divide
incdi
pushdi
popdx
movah,9
int21h
popdi
popbx
popdx
ret
@@Temp_Savedb7dup(?)
Dec_ASCIIEndP
;-------------------------------------
;功能:把AL中的二进制无符号数作为小数转换成显式的十进制ASCII码,
;并送显示屏显示,未考虑四舍五入
;入口:AH=二进制数,BH=除数,CX=保留小数位数
;出口:在当前光标位置显示转换后的ASCII码数字
Dec_FracProcNear
pushax
movdl,'.'
callOutput_Chr;显示一个小数点
popax
movbl,10;乘数
@@Dec_Frac:moval,ah;余数不为0,处理小数部分
mulbl;余数乘10,继续做除法
divbh;除以除数,取商数作为结果的一位小数
oral,30h
movdl,al
callOutput_Chr;显示一位小数
loop@@Dec_Frac
ret
Dec_FracEndP
;-------------------------------------
Studentsequ30;学生人数
Temp_Cursordw?;输入分数时,当前分数光标位置
Score_Tabdb6dup(0);各分数段计数
prompt_Strdb'Pleaseinputthescores:$'
prompt_MaxdbCR,LF,CR,LF,'Maximum:$';提示显示最高分
prompt_MindbCR,LF,'Minimum:$';提示显示最低分
prompt_Resdb'00---59:$'
prompt_AvedbCR,LF,'Average:$';提示显示平均分
Press_KeydbCR,LF,CR,LF,'Pressanykeytoexit...$'
Start:pushcs
popds
pushcs
popes;使数据段、附加段与代码段同段
;-------------------------------------
;1、输入成绩
Outputprompt_Str;提示输入成绩
mov@@Digits,3;十进制数字位数
mov@@Type_Data,'B';保存的数据类型。B=字节类型,W=字类型
leadi,List_Score;成绩存放地址
movcx,Students
Input_Score:callGetCursor;取光标位置
movdx,wordptrCursor_Row
movTemp_Cursor,dx;保存当前光标位置
callInput_Digit;输入成绩
cmpcx,1
je@@Next_0
movdx,Temp_Cursor
adddh,3
movCursor_Row,dl
movCursor_Col,dh
callSetCursor;置光标位置
movdl,','
callOutput_Chr;显示一个字符
@@Next_0:loopInput_Score
;-------------------------------------
;2、求最高分、最低分并显示
cld
leasi,List_Score;学生成绩存储区地址
lodsb;将第一个元素读入AL
movah,al;AH=最高分,AL=最低分
movcx,Students-1
Compare:cmpal,[si];当前最低分与当前元素比较
jbe$+4;若小于或等于,不更新最低分,转去与最高分比较
moval,[si];当前最低分大于当前元素,装入新的最低分
cmpah,[si];当前最高分与当前元素比较
jae$+4;若大于或等于,不更新最高分
movah,[si];当前最高分小于当前元素,装入新的最高分
incsi;增1,准备处理下一个分数
loopCompare
xchgah,al
pushax
Outputprompt_Max;提示显示最高分
popax
pushax
xorah,ah
callDec_ASCII;显示最高分
Outputprompt_Min;提示显示最低分
popax
xchgah,al
xorah,ah
callDec_ASCII;显示最低分
;-------------------------------------
;3、统计低于60分、60-69、70-79、80-89、90-100各个分数段人数并显示
callOutput_CTLF;输出一个回车、换行
callOutput_CTLF;输出一个回车、换行
leasi,List_Score
xorbx,bx;总分初值
movdl,10;用于除10
movcx,Students
@@Statics:lodsb;提取成绩
xorah,ah
addbx,ax;累计总分
divdl;除10
cmpal,5;>5,及格
ja$+4
moval,5;<=5,不及格
subal,5;减5,分数段计数地址偏移量
cbw;
pushax
popdi
incScore_Tab[di];计数
loop@@Statics;循环,统计下一个成绩
moval,Score_Tab[5];取100分人数
addScore_Tab[4],al;加到90-100分数段
pushbx;入栈保存总分
movbl,59h
movcx,5
leasi,Score_Tab;各分数段计数数组首地址
leadx,prompt_Res;统计结果字符串地址
List_Res:movah,9;显示分数段提示信息
int21h
lodsb;读入计数值
xorah,ah
callDec_ASCII;显示统计结果
callOutput_CTLF;输出一个回车、换行
moval,bl
incal
daa
movbl,al
pushcx
movcl,4
xorah,ah
shlax,cl
shral,cl
orax,3030h
xchgah,al
movwordptrPrompt_Res,ax
moval,bl
addal,9
movbl,al
xorah,ah
shlax,cl
shral,cl
orax,3030h
xchgah,al
movwordptrPrompt_Res[5],ax
popcx
loopList_Res
;-------------------------------------
;4、计算并显示平均分
Outputprompt_Ave;提示显示平均分
movbl,Students
popax;总分出栈
divbl;平均分取整数部分
movbh,ah;保存余数
xorah,ah
callDec_ASCII;显示平均分
movah,bh;余数
movbh,bl;除数
movcx,2;保留小数位数
callDec_Frac;把AL中的二进制无符号数作为小数转换成显式的十进制ASCII码
;-------------------------------------
OutputPress_Key
movah,1
int21h
Exit_Proc:movah,4ch;结束程序
int21h
List_Score:;学生成绩存储区
CodeENDS
ENDStart;编译到此结束