9号功能输出问题
时间:2011-11-21
来源:互联网
本程序是从键盘输入学生姓名和成绩,按成绩升序排序,并显示结果
DATAS SEGMENT
INFOR0 DB 0AH,0DH,'SORT=$'
INFOR1 DB 0AH,0DH,'INPUT NAME:$'
INFOR2 DB 0AH,0DH,'SCORE:$'
N EQU 8 ;姓名长度
M EQU 4 ;成绩长度(3位+回车符)
P EQU 3 ;输入的人数
Q EQU 3 ;成绩位数
BUFF1 DB N,?,N DUP(0),'$'
BUFF2 DB M,?,M DUP(0),'$'
SNAME DB P DUP(N+1 DUP(0)) ;保存姓名
SCORE1 DW P DUP(M+1 DUP(0)) ;保存成绩
SCORE2 DW P DUP(M+1 DUP(0))
CIXU DB P DUP(0) ;输入次序
X DW ?
SIGN1 DW 0
SIGN2 DW 0
CONT DB '1'
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
MAIN PROC FAR
START:
MOV AX,DATAS
MOV DS,AX
MOV ES,AX
MOV BX,0
MOV CX,0
CALL INPUT
CALL SORT
CALL PRINT
MOV AH,4CH
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;输入姓名成绩
INPUT PROC
INC BX
CMP BX,P
JA EXIT
LEA DX,INFOR1
MOV AH,9
INT 21H
LEA DX,BUFF1
MOV AH,10
INT 21H
MOV AL,BUFF1+1 ;实际输入个数
ADD AL,2 ;加2,包含buff1的0,1号单元
MOV AH,0
MOV SI,AX
MOV BUFF1[SI],0 ;回车0d换为0,便于输出显示
LEA DX,INFOR2
MOV AH,9
INT 21H
MOV AL,BUFF2+1
ADD AL,2
MOV AH,0
MOV SI,AX
MOV BUFF2[SI],0
MOV CIXU[BX-1],BL
CMP BX,1
JZ LET1
ADD SIGN1,N+1
ADD SIGN2,Q
LET1:
CALL COPY
JMP INPUT
EXIT:
RET
INPUT ENDP
;数据转存
COPY PROC
MOV CX,N+1
LEA SI,BUFF1+2
LEA DI,SNAME
ADD DI,SIGN1
CLD
REP MOVSB
MOV CX,N
MOV AX,'$'
LEA DI,BUFF1+2
REP STOSB
MOV CX,M+1
LEA SI,BUFF2+2
LEA DI,SCORE1
ADD DI,SIGN2
CLD
REP MOVSB
LEA SI,BUFF2+2
MOV DI,SIGN2
CALL CHANGE
RET
COPY ENDP
;十进制数ASCII→二进制
CHANGE PROC
MOV X,0
MOV CX,[SI-1]
AND CX,000FH
REPT2:
MOV AL,[SI]
CMP AL,30H
JL EXIT1
CMP AL,39H
JG EXIT1
AND AX,000FH
XCHG AX,X
MOV DX,10
MUL DX
ADD X,AX
INC SI
LOOP REPT2
MOV AX,X
MOV SCORE2[DI],AX
MOV X,0
ADD SIGN2,2
EXIT1:RET
CHANGE ENDP
;排序
SORT PROC
MOV CX,P
DEC CX
LOOP1:PUSH CX
MOV BX,0
MOV SI,0
LOOP2:MOV AX,SCORE2[BX]
CMP AX,SCORE2[BX+M+1]
JGE NEXT
XCHG AX,SCORE2[BX+M+1]
MOV SCORE2[BX],AX
MOV AL,CIXU[SI]
XCHG AL,CIXU[SI+1]
MOV CIXU[SI],AL
NEXT:ADD BX,M+1
INC SI
LOOP LOOP2
POP CX
LOOP LOOP1
RET
SORT ENDP
;输出
PRINT PROC
LEA DX,INFOR0
MOV AH,9
INT 21H
MOV CX,P
MOV BX,0
MOV AX,0
MOV DI,0
REPT3:
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
INT 21H
MOV DL,CONT
MOV AH,2
INT 21H
INC CONT
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
INT 21H
MOV AX,0
MOV AL,CIXU[DI]
DEC AL
MOV BL,9
MUL BL
LEA DX,SNAME
ADD DX,AX
MOV AH,9
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV AX,0
MOV BX,0
MOV AL,CIXU[DI]
DEC AL
MOV BL,5
MUL BL
LEA DX,SCORE1
ADD DX,AX
MOV AH,9
INT 21H
INC DI
LOOP REPT3
RET
PRINT ENDP
CODES ENDS
END START
为什么这里将回车换成0会便于输出呢。为什么它能正确输出呢?用9号功能不是碰到$符号是结束吗。而这个程序似乎是为每一个姓名或成绩分配了一个固定长度的缓冲区,$符号是放在最后面的。如果输入的姓名没有达到固定长度时就会有空余字符,按理说是会输出乱码的,但它却正常输出了,费解!
这是一个郑晓薇《汇编语言》的一个程序,有看懂的能解释一下么
DATAS SEGMENT
INFOR0 DB 0AH,0DH,'SORT=$'
INFOR1 DB 0AH,0DH,'INPUT NAME:$'
INFOR2 DB 0AH,0DH,'SCORE:$'
N EQU 8 ;姓名长度
M EQU 4 ;成绩长度(3位+回车符)
P EQU 3 ;输入的人数
Q EQU 3 ;成绩位数
BUFF1 DB N,?,N DUP(0),'$'
BUFF2 DB M,?,M DUP(0),'$'
SNAME DB P DUP(N+1 DUP(0)) ;保存姓名
SCORE1 DW P DUP(M+1 DUP(0)) ;保存成绩
SCORE2 DW P DUP(M+1 DUP(0))
CIXU DB P DUP(0) ;输入次序
X DW ?
SIGN1 DW 0
SIGN2 DW 0
CONT DB '1'
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS
MAIN PROC FAR
START:
MOV AX,DATAS
MOV DS,AX
MOV ES,AX
MOV BX,0
MOV CX,0
CALL INPUT
CALL SORT
CALL PRINT
MOV AH,4CH
INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;输入姓名成绩
INPUT PROC
INC BX
CMP BX,P
JA EXIT
LEA DX,INFOR1
MOV AH,9
INT 21H
LEA DX,BUFF1
MOV AH,10
INT 21H
MOV AL,BUFF1+1 ;实际输入个数
ADD AL,2 ;加2,包含buff1的0,1号单元
MOV AH,0
MOV SI,AX
MOV BUFF1[SI],0 ;回车0d换为0,便于输出显示
LEA DX,INFOR2
MOV AH,9
INT 21H
MOV AL,BUFF2+1
ADD AL,2
MOV AH,0
MOV SI,AX
MOV BUFF2[SI],0
MOV CIXU[BX-1],BL
CMP BX,1
JZ LET1
ADD SIGN1,N+1
ADD SIGN2,Q
LET1:
CALL COPY
JMP INPUT
EXIT:
RET
INPUT ENDP
;数据转存
COPY PROC
MOV CX,N+1
LEA SI,BUFF1+2
LEA DI,SNAME
ADD DI,SIGN1
CLD
REP MOVSB
MOV CX,N
MOV AX,'$'
LEA DI,BUFF1+2
REP STOSB
MOV CX,M+1
LEA SI,BUFF2+2
LEA DI,SCORE1
ADD DI,SIGN2
CLD
REP MOVSB
LEA SI,BUFF2+2
MOV DI,SIGN2
CALL CHANGE
RET
COPY ENDP
;十进制数ASCII→二进制
CHANGE PROC
MOV X,0
MOV CX,[SI-1]
AND CX,000FH
REPT2:
MOV AL,[SI]
CMP AL,30H
JL EXIT1
CMP AL,39H
JG EXIT1
AND AX,000FH
XCHG AX,X
MOV DX,10
MUL DX
ADD X,AX
INC SI
LOOP REPT2
MOV AX,X
MOV SCORE2[DI],AX
MOV X,0
ADD SIGN2,2
EXIT1:RET
CHANGE ENDP
;排序
SORT PROC
MOV CX,P
DEC CX
LOOP1:PUSH CX
MOV BX,0
MOV SI,0
LOOP2:MOV AX,SCORE2[BX]
CMP AX,SCORE2[BX+M+1]
JGE NEXT
XCHG AX,SCORE2[BX+M+1]
MOV SCORE2[BX],AX
MOV AL,CIXU[SI]
XCHG AL,CIXU[SI+1]
MOV CIXU[SI],AL
NEXT:ADD BX,M+1
INC SI
LOOP LOOP2
POP CX
LOOP LOOP1
RET
SORT ENDP
;输出
PRINT PROC
LEA DX,INFOR0
MOV AH,9
INT 21H
MOV CX,P
MOV BX,0
MOV AX,0
MOV DI,0
REPT3:
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
INT 21H
MOV DL,CONT
MOV AH,2
INT 21H
INC CONT
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
INT 21H
MOV AX,0
MOV AL,CIXU[DI]
DEC AL
MOV BL,9
MUL BL
LEA DX,SNAME
ADD DX,AX
MOV AH,9
INT 21H
MOV DL,0AH
MOV AH,2
INT 21H
MOV DL,0DH
MOV AH,2
INT 21H
MOV AX,0
MOV BX,0
MOV AL,CIXU[DI]
DEC AL
MOV BL,5
MUL BL
LEA DX,SCORE1
ADD DX,AX
MOV AH,9
INT 21H
INC DI
LOOP REPT3
RET
PRINT ENDP
CODES ENDS
END START
为什么这里将回车换成0会便于输出呢。为什么它能正确输出呢?用9号功能不是碰到$符号是结束吗。而这个程序似乎是为每一个姓名或成绩分配了一个固定长度的缓冲区,$符号是放在最后面的。如果输入的姓名没有达到固定长度时就会有空余字符,按理说是会输出乱码的,但它却正常输出了,费解!
这是一个郑晓薇《汇编语言》的一个程序,有看懂的能解释一下么
作者: ncist_jianeng 发布时间: 2011-11-21
乱码,0 字节不会乱码吧,显示的是空白而已,所以,即便是不足长度,也是看不出来的。
作者: zara 发布时间: 2011-11-21
引用楼主 ncist_jianeng 的回复:
本程序是从键盘输入学生姓名和成绩,按成绩升序排序,并显示结果
DATAS SEGMENT
INFOR0 DB 0AH,0DH,'SORT=$'
INFOR1 DB 0AH,0DH,'INPUT NAME:$'
INFOR2 DB 0AH,0DH,'SCORE:$'
N EQU 8 ;姓名长度
M EQU 4 ;成绩长度(3位+回车符)
P EQU 3 ;输……
本程序是从键盘输入学生姓名和成绩,按成绩升序排序,并显示结果
DATAS SEGMENT
INFOR0 DB 0AH,0DH,'SORT=$'
INFOR1 DB 0AH,0DH,'INPUT NAME:$'
INFOR2 DB 0AH,0DH,'SCORE:$'
N EQU 8 ;姓名长度
M EQU 4 ;成绩长度(3位+回车符)
P EQU 3 ;输……
Assembly code
;本程序是从键盘输入学生姓名和成绩,按成绩升序排序,并显示结果 DATAS SEGMENT INFOR0 DB 0AH,0DH,'SORT=$' INFOR1 DB 0AH,0DH,'INPUT NAME:$' INFOR2 DB 0AH,0DH,'SCORE:$' N EQU 8 ;姓名长度 M EQU 4 ;成绩长度(3位+回车符) P EQU 3 ;输入的人数 Q EQU 3 ;成绩位数 BUFF1 DB N,?,N DUP(0),'$' BUFF2 DB M,?,M DUP(0),'$' SNAME DB P DUP(N+1 DUP(0)) ;保存姓名 SCORE1 DW P DUP(M+1 DUP(0)) ;保存成绩 SCORE2 DW P DUP(M+1 DUP(0)) CIXU DB P DUP(0) ;输入次序 X DW ? SIGN1 DW 0 SIGN2 DW 0 CONT DB '1' DATAS ENDS CODES SEGMENT ASSUME CS:CODES,DS:DATAS MAIN PROC FAR START: MOV AX,DATAS MOV DS,AX MOV ES,AX MOV BX,0 MOV CX,0 CALL INPUT CALL SORT CALL PRINT MOV AH,4CH INT 21H MOV AH,4CH INT 21H MAIN ENDP ;--------------------------------------------------------------------- ;输入姓名成绩 ;--------------------------------------------------------------------- INPUT PROC INC BX CMP BX,P ;到达输入的最大人数了吗 JA EXIT ;超过了,退出 LEA DX,INFOR1 ;显示提示信息 MOV AH,9 INT 21H LEA DX,BUFF1 ;接收BUFF1 MOV AH,10 INT 21H MOV AL,BUFF1+1 ;实际输入个数 ADD AL,2 ;加2,包含buff1的0,1号单元 MOV AH,0 MOV SI,AX MOV BUFF1[SI],0 ;回车0d换为0,便于输出显示 LEA DX,INFOR2 ;显示提示信息 MOV AH,9 INT 21H ;---------------- ;这里得进输入串的功能 LEA DX,BUFF2 ;接收BUFF2 MOV AH,10 INT 21H ;-------------------- MOV AL,BUFF2+1 ;实际输入的字符数 ADD AL,2 ;追回2个字节 MOV AH,0 MOV SI,AX MOV BUFF2[SI],0 ;换为0 MOV CIXU[BX-1],BL ;BX初值为3 CMP BX,1 JZ LET1 ;第一次不需要设置了,跳出 ADD SIGN1,N +1 ;姓名长度 ADD SIGN2,Q ;成绩位数 LET1: CALL COPY JMP INPUT EXIT: RET INPUT ENDP ;--------------------------------------------------------------------- ;数据转存 ;--------------------------------------------------------------------- COPY PROC MOV CX,N+1 ;姓名长度+1(连最后的'$'也包括进来了) LEA SI,BUFF1+2 ; LEA DI,SNAME ;目标缓冲区 ADD DI,SIGN1 ;调整接收位置 CLD REP MOVSB ;复制姓名 MOV CX,N MOV AX,'$' LEA DI,BUFF1+2 REP STOSB ;将串BUFF1+2置'$' ;有了上面两处的置'$',所以用dos 中断9号功能显示是可行的。 MOV CX,M+1 LEA SI,BUFF2+2 LEA DI,SCORE1 ADD DI,SIGN2 CLD REP MOVSB ;复制成绩 LEA SI,BUFF2+2 MOV DI,SIGN2 CALL CHANGE ;将成绩转换成二进制 RET COPY ENDP ;--------------------------------------------------------------------- ;十进制数ASCII→二进制 ;--------------------------------------------------------------------- CHANGE PROC MOV X,0 MOV CX,[SI-1] ;实际字符数 AND CX,000FH ;实际字符数 REPT2: MOV AL,[SI] CMP AL,30H JL EXIT1 CMP AL,39H JG EXIT1 AND AX,000FH XCHG AX,X ;X保存上次的积 MOV DX,10 MUL DX ADD X,AX ;X保存上次的积 INC SI LOOP REPT2 MOV AX,X MOV SCORE2[DI],AX MOV X,0 ADD SIGN2,2 EXIT1: RET CHANGE ENDP ;--------------------------------------------------------------------- ;排序 ;--------------------------------------------------------------------- SORT PROC MOV CX,P DEC CX ;最大人数-1 LOOP1: PUSH CX MOV BX,0 MOV SI,0 LOOP2: MOV AX,SCORE2[BX] CMP AX,SCORE2[BX+M+1] JGE NEXT ;交换成绩 XCHG AX,SCORE2[BX+M+1] MOV SCORE2[BX],AX ;交换名次 MOV AL,CIXU[SI] XCHG AL,CIXU[SI+1] MOV CIXU[SI],AL NEXT: ADD BX,M+1 ;指向下一成绩 INC SI ;指向下一名次 LOOP LOOP2 POP CX LOOP LOOP1 ;--CX , 如果cx!=0 再循环 ;(算法不科学,如果输入就是排好序的, ;那不是也要循环cx次?) RET SORT ENDP ;--------------------------------------------------------------------- ;输出 ;--------------------------------------------------------------------- PRINT PROC LEA DX,INFOR0 MOV AH,9 INT 21H MOV CX,P MOV BX,0 MOV AX,0 MOV DI,0 REPT3: ;回车换行 MOV DL,0AH MOV AH,2 INT 21H MOV DL,0DH INT 21H ;显示count MOV DL,CONT ;(如果人数多于9个什么显示什么?) MOV AH,2 INT 21H INC CONT ;(如果人数多于9个什么显示什么?) ;回车换行 MOV DL,0AH MOV AH,2 INT 21H MOV DL,0DH INT 21H MOV AX,0 MOV AL,CIXU[DI] DEC AL MOV BL,9 ;姓名域尺寸 MUL BL LEA DX,SNAME ADD DX,AX MOV AH,9 INT 21H ;换行回车(应该0Dh在前) MOV DL,0AH MOV AH,2 INT 21H MOV DL,0DH MOV AH,2 INT 21H MOV AX,0 MOV BX,0 MOV AL,CIXU[DI] DEC AL MOV BL,5 ;成绩域尺寸 MUL BL LEA DX,SCORE1 ADD DX,AX MOV AH,9 INT 21H INC DI LOOP REPT3 RET PRINT ENDP CODES ENDS END MAIN ;START
作者: gsy999 发布时间: 2011-11-21
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28