汇编语言程序设计:从键盘上输入20个有符号数,将他们排序并在屏幕上显示,求程序具体解释,最好能有大概的流程过程说明
求大神下面程序具体解释
DATA SEGMENT
NOTE0 DB 'Note: The character that separates the integers can be any visible ASCII except ten digits(',27H,'0',27H,'-',27H,'9',27H,').',0DH,0AH,'$'
NOTE1 DB 0DH,0AH,'==================================================================',0DH,0AH ;0DH和0AH分别是回车和换行的ASCII码
DB 'Please input 20 (or less) decimal integers (-32768 to +32767):',0DH,0AH,'$' ;'$'是字符串的结束标志
NOTE2 DB 0DH,0AH,'==================================================================',0DH,0AH
DB 0DH,0AH,'The inputed integers: ','$'
NOTE3 DB 0DH,0AH,'==================================================================',0DH,0AH
DB 0DH,0AH,'How many decimal integers? ','$'
NOTE4 DB 0DH,0AH,'The sorted result: ',0DH,0AH,'$'
ERR_STR DB 0DH,0AH,'******************************************************************',0DH,0AH
DB 'Input error!',0DH,0AH
CON_STR DB 0DH,0AH,'******************************************************************',0DH,0AH
DB 0DH,0AH,'Continue? Y or N?','$'
DEC_STR DB 200 ;用来存放输入的原始数据
DB 60 ;db 60意思是定义一个字节初始值为60
DB 150 DUP('$') ;db 100 dup (?)意思是定义100个未经初始化的字节; db ?意思是定义一个未经初始化的字节
TOTAL DB 3 DUP('$') ;用来记录输入的数字个数
DEC_NUM DW 30 DUP(?) ;用来存放将输入的ASCII码转换成2进制数以便比较的结果
OUT_STR DB 150 DUP('$') ;存放待输出的字符组信息
DATA ENDS
STACK SEGMENT STACK
STT DB 100 DUP(60) ;堆栈
STACK ENDS
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,STACK
MOV SS,AX ;初始化ss
MOV AX,DATA
MOV DS,AX
;---------------------------------- 输出提示信息
LEA DX,NOTE0 ;直接显示NOTE0
MOV AH,09H ;显示
INT 21H ;调用dos
DISP0: LEA DX,NOTE1 ;直接显示NOTE1
MOV AH,09H
INT 21H
LEA DX,DEC_STR ;将原始数据存入该空间
MOV AH,0AH ;字符串
INT 21H
MOV AL,BYTE PTR[DEC_STR+2] ;输入合法性的标志:开头是数字或者符号 ;将DEC_STR的偏移地址+2指向的第一个字节赋值给AL
CMP AL,'0' ;条件判转指令本身占两个字节
JAE CMP1 ;A为大于,B为小于,E为等于
CMP AL,'+' ;检验AL寄存器内的值是不是+
JE DISP2
CMP AL,'-'
JE DISP2
JMP DISP1 ;JMP 无条件跳转
CMP1: CMP AL,'9'
JBE DISP2 ; 0〈=?〈=9 跳转到DISP2
DISP1: LEA DX,ERR_STR
MOV AH,09H ;显示
INT 21H
CON_YN: MOV AH,01H ;程序结束处询问是否需要继续
INT 21H
CMP AL,'Y' ;检验AL寄存器内的值是不是Y
JE DISP0
CMP AL,'y'
JE DISP0
CMP AL,'N'
JE OVER0
CMP AL,'n'
JE OVER0
OVER0: JMP OVER ;用以结束程序
DISP2: LEA DX,NOTE2 ;将输入的数据输出以便用户对照其正确性
MOV AH,09H ;显示NOTE2
INT 21H
LEA DX,[DEC_STR+2]
MOV AH,09H
INT 21H
;===============================COUNT HOW MANY DECIMAL INTEGERS 计算个数
LEA SI,DEC_STR
MOV CL,BYTE PTR[SI+1] ;CL中存放输入的总字符数 ;BYTE PTR用来定义所存入的是字节单元。[si+1]以字节单元存入SI中
MOV CH,0
PUSH CX ;cx的值压入堆栈保存
MOV AL,0 ;AL用来计数数字个数
LP1: MOV DL,BYTE PTR[SI+2] ;如果输入数字,符号则继续读下一位,如果输入其他字符则AL加一,这也是开头第一个字母不能为其他字符的原因
CMP DL,'+'
JE MOV_PTR
CMP DL,'-'
JE MOV_PTR
CMP DL,'0'
JL MOV_INC ;JL小于0跳转到MOV_INC
CMP DL,'9'
JLE MOV_PTR
MOV_INC:INC AL ;加一
MOV_PTR:INC SI
LOOP LP1
INC AL
CBW ;将AL拓展到AX中
MOV DEC_NUM,AX ;将2进制形式的计数结果放入该单元
MOV CL,10
DIV CL ;除以10后,AL中放的是结果(十位数),AH中放的是余数(个位数)
ADD AX,3030H ;加3030H后将十位数和个位数分别转换成ASCII码
LEA DI,TOTAL
MOV BYTE PTR[DI],AL
MOV BYTE PTR[DI+1],AH
MOV BYTE PTR[DI+2],'$' ;将ASCII形式的计数结果放入单元以便输出,$符号为代码的结束
LEA DX,NOTE3 ;显示NOTE3,输出计数结果
MOV AH,9
INT 21H
LEA DX,TOTAL ;小小的处理使得第一位是0时自动缺省
CMP0: MOV BX,DX
CMP BYTE PTR [BX],'0'
JNE DISPLAY
INC DX
DISPLAY:MOV AH,9
INT 21H
;==================================ASCII to DECIMAL
LEA DX,[DEC_STR+2] ;从DX指向的单元读入
MOV CX,DEC_NUM
LEA BX,DEC_NUM ;写进BX指向的单元
ADD BX,2
T1: CALL ASC2DEC ;调用ASCII码转换
MOV [BX],AX ;将处理后的数放入储存单元
ADD BX,2
ADD DX,SI ;DX指向新位置
LOOP T1
;==================================Sort binary gigits
CALL COMP ;冒泡排序,算法很经典,就不过多标注了
;==================================NOTE4 ;输出结果提示
LEA DX,NOTE4
MOV AH,09H
INT 21H
;==================================DECIMAL TO ASCII ;将排序后的2进制数用ASCII码表示并打印出来
LEA BX,DEC_NUM
mov cx,DEC_NUM
ADD BX,2
D2A: MOV AX,[BX] ;读出二进制数放在AX中
CALL DEC2ASC ;调用转化和打印过程
MOV DL,' ' ;输出空格
MOV AH,2 ;在DOS系统功能调用(INT 21H)这个表里:ah放2,是2号功能,字符输出,并且要输出的字符是已经放在dl里面的
INT 21H
ADD BX,2 ;后移,空两个字节
LOOP D2A
LEA DX,CON_STR
MOV AH,09H
INT 21H
JMP CON_YN ;询问是否继续
OVER: MOV AH,4CH ;带返回码的结束,AL=返回码
INT 21H
MAIN ENDP
;-----------------------------------ASCII TO DECIMAL NUMBER ASCII码转十进制数
ASC2DEC PROC NEAR ;定义函数
PUSH BX ;入栈保护
PUSH CX
PUSH DX
MOV AX,0 ;AX初始为0,采用乘10相加的方式转换
MOV SI,DX
PUSH SI
MOV DL,[SI]
CMP DL,'-' ;如果读入的是负数则置CL为1最后处理
JNE L0
MOV CL,1
INC SI
MOV DL,[SI]
JMP L4
L0: CMP Dl,'+'
JNE L1
INC SI
MOV DL,[SI]
L1: MOV CL,0 ;正数置CL为0
L4: AND DL,0FH
MOV DH,0
ADD AX,DX
INC SI
MOV DL,[SI]
CMP DL,'0'
JL L2
CMP DL,'9'
JG L2
CALL TIMBY10 ;调用乘10进程
JMP L4
L2: CMP CL,1 ;如果是负数,对其求反
JNE L3
NEG AX
L3: POP DI ;DI出栈
SUB SI,DI ;SI减去初始位置,计算相对位移量
INC SI
POP DX
POP CX
POP BX
RET
ASC2DEC ENDP
;==================================AX TIME BY 10
TIMBY10 PROC NEAR
MOV BX,AX
SHL AX,1 ;乘2
SHL AX,1 ;再乘2
ADD AX,BX ;加一倍,现在相当于乘了5
SHL AX,1 ;乘2,总共是乘了10
RET
TIMBY10 ENDP
;==================================SORT DECIMAL NUMBERS 十进制数排序
COMP PROC NEAR ;保护
PUSH AX
PUSH BX
PUSH CX
PUSH DI
MOV AX,DATA
MOV DS,AX
LEA DI,DEC_NUM
MOV CX,WORD PTR[DI] ;计数
DEC CX
C1: MOV DX,CX
MOV BH,0
C2: ADD DI,2
MOV AX,[DI]
CMP AX,[DI+2]
JLE CONT1
XCHG AX,[DI+2]
MOV [DI],AX
MOV BH,1
CONT1: LOOP C2
CMP BH,0
JE STOP
MOV CX,DX
LEA DI,DEC_NUM
LOOP C1
STOP: LEA BX,DEC_NUM
MOV AX,[BX+8]
POP DI
POP CX
POP BX
POP AX
RET
COMP ENDP
;==================================DECIMAL NUMBER TO ASCII转换成ASCII码
DEC2ASC PROC
PUSH BX ;保护
PUSH CX
LEA DI,OUT_STR ;将处理后的放入DI
MOV DX,DI
CMP AX,0
JNE NON_0
ZERO: MOV BYTE PTR[DI],'0' ;如果是0
MOV BYTE PTR[DI+1],'$'
JMP OUT_ASC
NON_0: TEST AX,8000H ;不是0
JZ PTIVE ;判断符号,是正号跳转
NTIVE: NEG AX ;取反
MOV BYTE PTR[DI],'-' ;置负号
JMP CON
PTIVE: MOV BYTE PTR[DI],'+' ;置正号
CON: INC DI
MOV DX,0
MOV CX,10000 ;万位
IDIV CX ;带符号数除法
ADD AL,30H ;加30H变成ASCII
MOV BYTE PTR[DI],AL
MOV AX,DX
MOV DX,0
MOV CX,1000 ;千位
IDIV CX
ADD AL,30H ;加30H变成ASCII
MOV BYTE PTR[DI+1],AL ;写入
MOV AX,DX
MOV CL,100 ;百位
IDIV CL
ADD AL,30H
MOV BYTE PTR[DI+2],AL
MOV AL,AH
MOV AH,0
MOV CL,10 ;十位
IDIV CL
ADD AL,30H
MOV BYTE PTR[DI+3],AL
ADD AH,30H
MOV BYTE PTR[DI+4],AH ;个位
OUT_SIG:LEA DI,OUT_STR
MOV DL,BYTE PTR[DI]
MOV AH,2
INT 21H
INC DI
MOV DX,DI
B2: CMP BYTE PTR[DI],'0'
JNE OUT_ASC
INC DI
INC DX
JMP B2
OUT_ASC:MOV AH,09H ;打印
INT 21H
POP CX
POP BX
RET
DEC2ASC ENDP
;==================================
CODE ENDS
END START