Shall be saved as .asm
file and compile -> .obj
-> .exe
(16bit) and run in command line window.
Hello World显示字符
DSEG SEGMENT
STRING DB 'HELLO,WORLD!',0DH,0AH,'$' ;定义显示的字符
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG, DS:DSEG
START: MOV AX,DSEG
MOV DS,AX
LEA DX,STRING ;获取显示字符串的首地址
MOV AH, 09H ;09H为调用显示功能
INT 21H
MOV AH,4CH ;调用返回dos
INT 21H ;软件中断,返回dos
CSEG ENDS
END START
5位数字十进制相加 Extremely buggy
DATAS SEGMENT
DATA1 DB 5 DUP(0)
DATA2 DB 5 DUP(0)
DATA3 DB 6 DUP(0)
addsign db ' + ' ,'$'
equalsign db ' = ' ,'$'
DATAS ENDS
;
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
START:
MOV AX,DATAS
MOV DS,AX
LEA BX,DATA1
MOV CX,5
INADD1:MOV AH,01H
INT 21H
MOV [BX],AL
INC BX
LOOP INADD1
LEA DX,addsign ;display add sign
MOV AH,09H
INT 21H
LEA SI,DATA2
MOV CX,05H
INADD2:MOV AH,01H
INT 21H
MOV [SI],AL
INC SI
LOOP INADD2
LEA DX,equalsign ;display equal sign
MOV AH,09H
INT 21H ;return to dos
LEA BX,DATA1+4
LEA SI,DATA2+4
LEA DI,DATA3+5
MOV CX,5
CLC ;clear CF flag
L1:MOV AL,[BX]
ADC AL,[SI]
AAA
PUSHF
OR AL,30H ;AL->ASCII
POPF
MOV [DI],AL
DEC DI
DEC BX
DEC SI
LOOP L1
MOV CL,6
JNC OUT1 ;没有进位直接输出
MOV byte ptr[DI],31H ;有进位给最高位赋1
OUT1:
MOV DL,[DI]
INC DI
MOV AH,02H
INT 21H
LOOP OUT1
MOV AH,4CH
INT 21H
CODES ENDS
END START
DATA SEGMENT
APP DB 35H,34H,33H,32H,31H,2BH,34H,35H,34H,33H,32H,3DH,0DH,0AH,'$ '
DATA1 DB 01H,02H,03H,04H,05H
DATA2 DB 02H,03H,04H,05H,04H
SUM DB 5 DUP(?),'$ '
;
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
LEA DX,APP
MOV AH,09H
INT 21H ;这里先把加数和被加数以加法的格式显示出来
MOV SI,OFFSET DATA1
MOV DI,OFFSET DATA2
MOV BX,OFFSET SUM
XOR CX,CX
MOV CL,5 ;给定加法位数
GO: MOV AL,[SI]
ADC AL,[DI]
AAA
PUSHF ;压入堆栈保护标志位
ADD SI,1
ADD DI,1
MOV [BX],AL
ADD [BX+4],30H ;将结果调整到ASCII码的形式,方便显示
DEC BX
POPF
LOOP GO
LEA DX,SUM
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END START
16-2进制转换
CRLF MACRO
MOV AH,02H
MOV DL,0DH
INT 21H
MOV AH,02H
MOV DL,0AH
INT 21H
ENDM
DATA SEGMENT
MARK DB ?
MESS DB'INPUT:$'
ERROR DB 0DH,0AH,'INPUT IS ERROR!',0DH,0AH,'$'
DATA ENDS
STACK SEGMENT
STA DW 32 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN:
MOV AX,DATA
MOV DS,AX
HEAD:CRLF
MOV MARK,0H
MOV AH,09H
LEA DX,MESS
INT 21H
CALL INPUTNUM
CMP MARK,01H
JE HEAD;
MOV CX,0010H
MOV BX,DX
SHOW:ROL BX,1
MOV DL,BL
AND DL,01H
ADD DL,30H
MOV AH,02H
INT 21H
LOOP SHOW
JMP HEAD
FIN:MOV AX,4C00H
INT 21H
INPUTNUM PROC NEAR
XOR DX,DX
GO:MOV AH,01H
INT 21H
CMP AL,0DH
JE HCHH
CMP AL,20H
JE FIN
CMP AL,30H
JB WRONG
SUB AL,30H
CMP AL,0AH
JB BINGO
CMP AL,11H
JB WRONG
SUB AL,07H
CMP AL,0FH
JBE BINGO
CMP AL,2AH
JB WRONG
CMP AL,2FH
JA WRONG
SUB AL,20H
BINGO:
MOV CL,04H
SHL DX,CL
XOR AH,AH
ADD DX,AX
JMP GO
WRONG:MOV AH,09H
MOV DX,OFFSET ERROR
INT 21H
MOV MARK,01H
HCHH:PUSH DX
CRLF
POP DX
RET
INPUTNUM ENDP
CODE ENDS
END BEGIN
屏幕显示可移动图形
DATA SEGMENT
UP DW 0,0DBDBH,0,0808H,0808H,0808H ;画炮口向上的坦克
DB 0AH
DW 0DBDBH,0DBDBH,0DBDBH,0808H,0808H,0808H
DB 0AH
DW 0DBDBH,0,0DBDBH
DOWN DW 0DBDBH,0,0DBDBH,0808H,0808H,0808H ;画炮口向下的坦克
DB 0AH
DW 0DBDBH,0DBDBH,0DBDBH,0808H,0808H,0808H
DB 0AH
DW 0,0DBDBH,0
LEFT DW 0,0DBDBH,0DBDBH,0808H,0808H,0808H ;画炮口向左的坦克
DB 0AH
DW 0DBDBH,0DBDBH,0,0808H,0808H,0808H
DB 0AH
DW 0,0DBDBH,0DBDBH
RIGHT DW 0DBDBH,0DBDBH,0,0808H,0808H,0808H ;画炮口向右的坦克
DB 0AH
DW 0,0DBDBH,0DBDBH,0808H,0808H,0808H
DB 0AH
DW 0DBDBH,0DBDBH,0
LENTH DW 32 ;画坦克所需字节数
FWD DW 0 ;坦克方向
LOCA DB 0BH,0DH,25H,2AH ;坦克的位置
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV ES,AX
LEA BP,UP ;取段地址
LOP:CALL CLEAR ;清屏
MOV AH,08H ;输入方向
INT 21H
CALL COMPARE ;对输入字符进行处理
MyESC:MOV AH,4CH ;退出
INT 21H
COMPARE PROC NEAR
CMP AL,1BH ;退出
JE MyESC
CMP AL,'w' ;是否输入向上走
JNE L2
MOV BX,FWD ;比较初始方向
CMP BX,0
JNE L1 ;如果初始方向不为上,则坦克转向
CMP LOCA[0],0 ;如果初始方向为上,则在不撞墙的情况下前进一格
JE L1
DEC LOCA[0] ;坦克上行减一
DEC LOCA[1] ;坦克下行减一
L1:MOV FWD,0 ;调整坦克方向
LEA BP,UP ;将画炮口向上的坦克的字符串偏移地址赋给寄存器
JMP LOP
L2:CMP AL,'s'
JNE L4
MOV BX,FWD
CMP BX,1
JNE L3
CMP LOCA[1],18H
JE L3
INC LOCA[0]
INC LOCA[1]
L3: MOV FWD,1
LEA BP,DOWN
JMP LOP
L4:CMP AL,'a'
JNE L6
MOV BX,FWD
CMP BX,2
JNE L5
CMP LOCA[2],1
JE L5
DEC LOCA[2]
DEC LOCA[2]
DEC LOCA[3]
DEC LOCA[3]
L5:MOV FWD,2
LEA BP,LEFT
JMP LOP
L6:CMP AL,'d'
JNE L8
MOV BX,FWD
CMP BX,3
JNE L7
CMP LOCA[3],4EH
JE L7
INC LOCA[2]
INC LOCA[2]
INC LOCA[3]
INC LOCA[3]
L7:MOV FWD,3
LEA BP,RIGHT
L8:JMP LOP
RET
COMPARE ENDP
CLEAR PROC NEAR
MOV AX,0600H ;清屏
MOV BH,0F4H
MOV CX,1
MOV DX,184EH
INT 10H
MOV DH,LOCA[0] ;取坦克上行左列为起始点画坦克
MOV DL,LOCA[2]
MOV AX,1301H
MOV BH,00
MOV BL,0F9H
MOV CX,LENTH
INT 10H
RET
CLEAR ENDP
CODE ENDS
END START
屏幕输入内容并自动滚动
CODES SEGMENT
ASSUME CS:CODES
;主程序
Main proc far
call Initializing
call get_char
ret
Main endp
;屏幕初始化
Initializing proc near
push ax
push bx
push cx
push dx
;设置外窗口属性
MOV AH,7 ;功能:屏幕初始化
MOV AL,0 ;page
MOV BH,70H ;白底黑字
MOV CH,1 ;row左上
MOV CL,2 ;column左上
MOV DH,23 ;row右下
MOV DL,77 ;column右下
INT 10H ;BIOS显示操作中断
;设置内窗口属性
MOV AH,7 ;功能:屏幕初始化
MOV AL,0 ;page
MOV BH,3FH ;浅青色底白字
MOV CH,2 ;row左上
MOV CL,4 ;column左上
MOV DH,22 ;row右下
MOV DL,75 ;column右下
INT 10H ;BIOS显示操作中断
;设置光标类型(大小)
MOV CH,12 ;光标起始行
MOV CL,13 ;光标结束行
MOV AH,1 ;设置光标类型
INT 10H ;DOS中断:显示操作
;初始化光标位置
MOV DH,22 ;屏幕显示行
MOV DL,4 ;屏幕显示列
MOV BH,0 ;显示页号
MOV AH,2 ;置光标位置
INT 10H ;BIOS显示操作中断
pop dx
pop cx
pop bx
pop ax
ret
Initializing endp
;键盘输入,直到Esc退出
get_char proc near
push ax
push dx
mov ah,1 ; 功能:从键盘输入一个字符并回显
int 21h
cmp al,1bh ; 判断按键是否ESC√
jz exit
cmp al,0DH ; 判断是否为回车键(要注意回车后不返回,而是等待继续输入)
jz EnterDeal ; 调转 回车键处理
mov ah,3 ; 读取当前光标位置
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
cmp dl,76 ; 判断是否最后一列(75+1)√(可用于设置字符显示宽度)
jz LastColumn ; 跳转 末列处理
loop get_char ; 继续输入
pop dx
pop ax
;退出程序
exit:
mov ah,4ch
int 21h ;DOS中断
get_char endp
;回车键处理-----------------;(把回车控制到内窗口-不处理会跳到屏幕左边界)
EnterDeal proc near
push ax
push dx
mov ah,3 ; 读取当前光标位置
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
mov ah,2 ; 功能:置光标位置
;mov dh,? ; 保持当前行
mov dl,4 ; 光标置内窗口左边界
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
jmp LastLine ; 继续末行判断
pop dx
pop ax
ret ; 返回主程序
EnterDeal endp
;末列处理
LastColumn proc near
push ax
push dx
mov ah,3 ; 读取当前光标位置
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
mov ah,2 ; 功能:置光标位置
add dh,1 ; 光标置下一行
mov dl,4 ; 光标置内窗口左边界
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
jmp LastLine ; 继续末行判断
pop dx
pop ax
ret ; 返回主程序
LastColumn endp
;末行判断-------------------; 末行(22+1)需要卷屏并上移光标
LastLine proc near
push ax
push dx
mov ah,3 ; 读取当前光标位置
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
cmp dh,23 ; 判断是否最后一行(22+1)
jne get_char ; 否:继续输入
;----------------------- ; 是:卷屏1行并上移光标
call scroll_screen ; 调用屏幕滚动
mov ah,3 ; 读取当前光标位置
;mov bh,0 ; 页号
int 10h ; BIOS显示操作中断
mov ah,2 ; 功能:置光标位置
mov dh,22 ; 光标置内窗口左边界
mov dl,4 ; 光标置内窗口左边界
int 10h ; BIOS显示操作中断
pop dx
pop ax
jmp get_char ; 继续输入
Lastline endp
;屏幕每次上卷1行---------------- ; 屏幕滚动必须要设置窗口滚动的范围,即cx,dx
scroll_screen proc near
push ax
push bx
push cx
push dx
mov al,1 ; 上卷的行数
mov bh,2FH ;
mov ch,2
mov cl,4
mov dh,22 ; 整屏滚动
mov dl,75
mov ah,6 ; 功能:屏幕上卷
int 10h ; BIOS显示操作中断
pop dx
pop cx
pop bx
pop ax
ret ; 返回调用程序
scroll_screen endp
CODES ENDS
END Main
学生成绩数据处理
info STRUC
s_class DB 4,?,2 DUP(' ')
s_id DB 7,?,5 DUP(' ')
s_name DB 8,?,6 DUP(' ')
s_score DB 3 DUP(' '),'.0$' ;分数需特殊处理
info ENDS
data SEGMENT
num_mes DB 0dh,0ah,'Please input the number of student(1-99):$'
cLass_mes DB 0dh,0ah,'CLASS(within 2 bits,end with dollar)',0dh,0ah,'$'
id_mes DB 0dh,0ah,'ID (within 4 bits,end with dollar)',0dh,0ah,'$'
name_mes DB 0dh,0ah,'NAME (within 5 bits,end with dollar)',0dh,0ah,'$'
score_mes DB 0dh,0ah,'SCORE (xx.x or xx,end with dollar)',0dh,0ah,'$' ;成绩输入整数或有一位小数
ave_mes DB 0dh,0ah,'AVERAGE SCORE:$'
stand_mes DB 0dh,0ah,'<60 60-70 70-80 80-90 90-100:',0dh,0ah,'$'
line DB 0dh,0ah,'$'
blank DB ' $'
student info 99 DUP(<>) ;数组
temp DB 8,?,6 DUP(' ') ;缓存输入的分数
s_num DW 0 ;存储学生数
sum_score DW 0 ;存储总分
;用于统计各个分数段人数
sco_60 DB '0'
sco_70 DB '0'
sco_80 DB '0'
sco_90 DB '0'
sco_100 DB '0'
sscore DB '100''$' ;要显示的分数,初值为满分100
n DW 10 ;十进制数权重
ssnum DB 3 DUP(0)
buffer1 DW 0 ;存储分数的整数位数据
buffer2 DW 0 ;存储分数的小数位
data ENDS
code SEGMENT
ASSUME CS:code,DS:data
start:
main PROC FAR
MOV AX,data
MOV DS,AX
;--------------------------------输入,存储信息
INPUTE: LEA AX,num_mes
MOV DX,AX
MOV AH,09h
INT 21h ;显示num_mes
;--------------------------------获得学生人数begin
XOR BX,BX ;清空BX
in_num:
MOV AH,01 ;输入字符
INT 21h;
CMP AL,0dh ;判断是否输入回车
JE new_l ;若输入结束则跳转
AND AL,0fh ;输入未结束 转换成非压缩的BCD码
MOV ssnum[BX],AL
INC BX ;输入未结束,则继续输入
JMP in_num
new_l:
CMP BX,3 ;输入数大于99,重新输入
JNC INPUTE
CMP BX,2 ;输入学生数大于10,还是小于10
JZ INPUTE_2 ;学生数大于10
JMP INPUTE_l ;学生数小于10,大于0
INPUTE_2:
MOV AH,ssnum ;输入数为两位数
MOV AL,ssnum[1]
AAD ;BCD码转换为二进制数
INPUTE_l:
MOV AL,ssnum
XOR AH,AH
MOV s_num,AX
;-----------------------------------------录入信息begin
MOV CX,s_num ;CX存放学生数
LEA BX,student ;变量student的首地址传给BX
loop1: ;循环读取每个学生信息
PUSH CX ;CX压栈
LEA DX,class_mes ;显示class_mes
MOV AH,09h
INT 21h ;
MOV DX,BX ;BX存放info结构体的s_class的地址
MOV AH,0ah ;输入学号到info结构体的s_class
INT 21h
LEA DX,id_mes ;显示id_mes
MOV AH,09h
INT 21h ;
ADD BX,4
MOV DX,BX
MOV AH,0ah ;输入学号到info结构体的s_id
INT 21h
LEA DX,name_mes ;显示name_mes
MOV AH,09h
INT 21h ;
ADD BX,7 ;BX存放info结构体的s_name的地址
MOV DX,BX ;输入姓名到info结构体的s_name
MOV AH,0ah
INT 21h
LEA DX,score_mes ;显示score_mes
MOV AH,09h
INT 21h
ADD BX,8 ;BX存放info结构体的s_score的地址
qqq:
LEA DX,temp ;输入成绩到缓冲区
MOV AH,0ah
INT 21h
XOR DI,DI ;清空DI
MOV AL,temp[1]
XOR AH,AH ;清空AH
MOV DI,AX ;DI中存放输入的字符数
MOV CX,DI ;循环次数为输入字符数
MOV SI,DI ;SI中存放输入的字符数
INC SI
jiance:
CMP temp[SI],'.' ;检测是否输入小数
JE xiaoshu ;若是,转到xiaoshu
DEC SI ;若否,继续检测下一位
LOOP jiance
MOV SI,2 ;输入为整数
JMP ddd
xiaoshu:
MOV SI,4 ;输入有小数
ddd:
MOV AL,temp[DI] ;将该位成绩由缓冲区输入到内存info结构体对应学生成绩项
MOV [BX+SI],AL
CMP DI,2 ;数据位比较完成
JE zzz
DEC DI ;输入下一位
DEC SI
JMP ddd
zzz:
POP CX ;CX出栈
CALL get_score ;求得成绩
ADD BX,6
LOOP loop1 ;下一个学生
;----------------------------------------------------结束录入
MOV AX,sum_score ;学生总成绩
XOR DX,DX
DIV s_num ;除以学生数
MOV sum_score,AX ;得到平均数 仍存储于sum_score
;--------------------------------------------排序,按成绩由大到小
MOV CX,s_num
DEC CX
CMP CX,0 ;若只有一个学生,直接输出
JE oout
LEA BX,student ;否则将学生数组的地址给BX
lll1: ;冒泡排序
MOV DX,CX ;保存外层循环次数,外层循环次数是数组个数减1
PUSH BX
lll2:
PUSH CX
MOV DI,BX ;保存当前学生地址
ADD BX,19 ;下一个学生
MOV CX,5 ;每个学生成绩有5位
XOR SI,SI ;清空SI
lll3: ;按位比较两同学的成绩,由高位到低位
MOV AL,[BX+SI] ;当前学生成绩赋值给AL
CMP AL,[BX+SI+25] ;比较当前学生与下一学生的成绩
JB swap ;若小于,交换
JA next_stu ;若大于,比较下一个学生
INC SI ;否则,比较下一位
LOOP lll3
swap: ;交换两学生全部信息
XOR CX,CX ;清空CX
MOV CX,26 ;一个学生的信息共占25字节
XOR SI,SI ;清空SI
MOV BX,DI ;恢复刚才比较的学生的地址
sswap:
MOV AL,[BX+SI] ;bx用作交换中的计数
XCHG AL,[BX+SI+25] ;按位交换
MOV [BX+SI],AL
INC SI
LOOP sswap
next_stu: ;下一个学生
POP CX
MOV DI,BX
ADD BX,25
LOOP lll2
POP BX
MOV CX,DX ;恢复外层循环次数
LOOP lll1
;---------------------输出-------------
oout:
MOV CX,s_num ;CX存放学生数
XOR BX,BX ;BX清空
LEA BX,student ;变量student的首地址给BX
ADD BX,2
MOV AH,09h ;显示字符串
CALL lline ;空行
xianshi:
CALL lline
MOV DX,BX ;DX指向要显示的学生
INT 21H
CALL bblank ;空格
ADD BX,4 ;显示学号
MOV DX,BX
INT 21H
CALL bblank ;空格
ADD BX,7 ;显示姓名
MOV DX,BX
INT 21H
CALL bblank
ADD BX,6 ;显示成绩
MOV DX,BX
INT 21H
CALL get_stand
ADD BX,8 ;显示下一个学生
LOOP xianshi
CALL lline
LEA AX,stand_mes
MOV DX,AX
MOV AH,09h
INT 21h ;显示stand_mes
MOV DL,sco_60 ;显示表示成绩小于60分人数的字符
MOV AH,2
INT 21h
CALL bblank
MOV DL,sco_70 ;显示60-70分人数
MOV AH,2
INT 21h
CALL bblank
CALL bblank
MOV DL,sco_80 ;显示70-80分人数
MOV AH,2
INT 21h
CALL bblank
CALL bblank
MOV DL,sco_90 ;显示80-90分人数
MOV AH,2
INT 21h
CALL bblank
CALL bblank
MOV DL,sco_100 ;显示90-100分人数
MOV AH,2
INT 21h
CALL get_ave ;显示平均成绩
MOV AH ,1 ;输入一个字符,方便显示结果,无实际意义
INT 21h
MOV AX,4c00h ;停机
INT 21H
;----------------------------------------------------------------------
get_score PROC NEAR
MOV SI,2
loop4:
MOV AL,temp[SI]
CMP AL,'.' ;比较当前位是否是小数点
JE ppoint ;若是,转到ppoint
CMP AL,'$' ;比较当前位是否结束
JE eend ;若是,转到eend
AND AX,000fh ;换成非压缩的BCD码,求得成绩
XCHG AX,buffer1 ;输入到分数整数位
MUL n ;AL中的数乘以十进制权重
ADD buffer1,AX
INC SI ;比较下一位
JMP loop4
ppoint:
INC SI ;比较下一位
MOV AL,temp[SI]
CMP AL,'$' ;比较当前位是否结束
JE eend ;若是,转到eend
AND AX,000fh ;换成非压缩的BCD码,求得成绩
MOV buffer2,AX ;输入到分数小数位
JMP ppoint ;比较下一位
eend: ;结束时加和
MOV AX,buffer1
MUL n
ADD AX,buffer2 ;整数部分加小数部分
ADD sum_score,AX
MOV buffer1,0 ;清空 buffer1和 buffer2
MOV buffer2,0
RET
get_score ENDP
;----------------------------------------------------------------------
get_stand PROC NEAR
PUSH AX ;保护环境
PUSH BX
PUSH DX
XOR AX,AX
CLD
MOV DX,[BX] ;首先比较该成绩是否为100,由高位到低位按位比较
AND DX,0F0FH ;由ASC码转换成数值
CMP DL, 01H ;百位是否为1
JNZ COMPARE ;若否,转到COMPARE
CMP DH, 0 ;若是,继续比较十位是否为0
JNZ COMPARE ;若否,转到COMPARE
MOV DX,[BX+2] ;若是,继续比较个位是否为0
AND DX,0FH
CMP DL, 0
JNZ COMPARE ;若否,转到COMPARE
JMP COMPARE_90 ;若是,则表示成绩为100,转到COMPARE_90
COMPARE: ;成绩不是100,直接比较十位即可
MOV DX,[BX]
AND DX,0F00H
CMP DH, 09H ;比较该位数是否>=90
JNC COMPARE_90 ;若是,转到COMPARE_90
CMP DH, 08H ;若否,继续比较是否>=80
JNC COMPARE_80 ;若是,转到COMPARE_80
CMP DH, 07H ;若否,继续比较是否>=70
JNC COMPARE_70 ;若是,转到COMPARE_70
CMP DH, 06H ;若否,继续比较是否>=60
JNC COMPARE_60 ;若是,转到COMPARE_60
XCHG AL, sco_60 ;若否,则<60分数段人数加1
INC AL
MOV sco_60, AL
JMP DONE
COMPARE_60: ;60-70分数段人数加1
XCHG AL, sco_70
INC AL
MOV sco_70, AL
JMP DONE
COMPARE_70: ;70-80分数段人数加1
XCHG AL, sco_80
INC AL
MOV sco_80, AL
JMP DONE
COMPARE_80: ;80-90分数段人数加1
XCHG AL, sco_90
INC AL
MOV sco_90, AL
JMP DONE
COMPARE_90: ;90-100分数段人数加1
XCHG AL, sco_100
INC AL
MOV sco_100, AL
JMP DONE
DONE: POP DX ;恢复环境
POP BX
POP AX
RET
get_stand ENDP
;----------------------------------------------------------------------
get_ave PROC NEAR ;求平均数
CALL lline ;空行
LEA AX,ave_mes ;显示平均数
MOV DX,AX
MOV AH,09h
INT 21h
CALL bblank ;空格
MOV AX,100
MUL s_num
CMP AX,sum_score ;是否全部为满分
JE ttt1 ;若是,转到ttt1
MOV AX,sum_score
XOR DI,DI ;清空DI
MOV DI,3
ttt2:
XOR DX,DX ;清空DX
DIV n ;AX除以权重10
OR DL,30h
DEC DI
MOV sscore[DI],DL ;放入显示分数的字符串
CMP AX,0 ;判断AX是否比较完
JE ttt3 ;若完成,转到ttt3
JMP ttt2 ;否则继续比较下一位,由低位向高位
ttt3:
MOV DL,sscore[DI] ;按位显示,由高位到低位
MOV AH,02h
INT 21h
CMP DI,1 ;当前位是否为个位
JE dot ;若是,显示小数点
CMP DI,2
JE dend
INC DI
JMP ttt3
dot: ;显示小数点
MOV DL,'.'
INT 21h
INC DI ;显示一位小数
JMP ttt3
ttt1: ;显示100分
XOR DX,DX
MOV DL,sscore
MOV AH,09h
INT 21h
dend:
RET
get_ave ENDP
;-------------------------------------------------------
lline PROC NEAR ;空行
LEA DX,line
MOV AH,09h
INT 21h ;
RET
lline ENDP
bblank PROC NEAR ;空格
LEA DX,blank
MOV AH,09h
INT 21h ;
RET
bblank ENDP
main ENDP
code ENDS
END start