9号功能输出问题

ncist_jianeng 2011-11-21 10:38:37
本程序是从键盘输入学生姓名和成绩,按成绩升序排序,并显示结果

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号功能不是碰到$符号是结束吗。而这个程序似乎是为每一个姓名或成绩分配了一个固定长度的缓冲区,$符号是放在最后面的。如果输入的姓名没有达到固定长度时就会有空余字符,按理说是会输出乱码的,但它却正常输出了,费解!
这是一个郑晓薇《汇编语言》的一个程序,有看懂的能解释一下么
...全文
119 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ncist_jianeng 2011-11-22
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 gsy999 的回复:]
引用楼主 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位+回车符……
[/Quote]
谢谢你的解释 ,我明白了
ncist_jianeng 2011-11-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zara 的回复:]
乱码,0 字节不会乱码吧,显示的是空白而已,所以,即便是不足长度,也是看不出来的。
[/Quote]

恩,就是跟你说的一样.我理解错了.
gsy999 2011-11-21
  • 打赏
  • 举报
回复
[Quote=引用楼主 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 ;输……
[/Quote]

;本程序是从键盘输入学生姓名和成绩,按成绩升序排序,并显示结果

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
zara 2011-11-21
  • 打赏
  • 举报
回复
乱码,0 字节不会乱码吧,显示的是空白而已,所以,即便是不足长度,也是看不出来的。

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧