超高分请教一道汇编语言编程问题

内容是编写由键盘输入10个4位的数据并将这些数由大到小或由小到大进行排序其结果输出在显示屏上的程序.程序已经写好:
DATA SEGMENT
LEN EQU 10
ARRAY DW 10 DUP(?)
MESS DB 0DH,0AH,'PLEASE INPUT NUMBERS',0DH,0AH,'INPUT:$'
ENTER DB 0DH,0AH,'$'
SY DB 0DH,0AH,'SORT END OUTPUT DATA :','$'
NUMBER DB 5,0,5 DUP(?)
CHANGE DB 0
DATA ENDS

STACK SEGMENT STACK
STA DB 64 DUP(0)
STACK_TOP DB 0
STACK ENDS

CODE SEGMENT
ASSUME CS:CODE, DS:DATA , SS:STACK

START: MOV AX, DATA
MOV DS, AX
MOV AX,STACK
MOV SS,AX
LEA SP, STACK_TOP
MOV BX, OFFSET ARRAY
MOV CX,LEN ;计数值LEN送CX
A :MOV AH,09H
LEA DX,MESS
INT 21H ;显示提示输入的信息
LEA DX,NUMBER
MOV AH,0AH
INT 21H
LEA DI,NUMBER
MOV DL,[DI+2]
SUB DL,30H
MOV AH,DL
SHL AH,01
SHL AH,01
SHL AH,01
SHL AH,01
MOV DL,[DI+3]
SUB DL,30H
ADD AH,DL
MOV DL,[DI+4]
SUB DL,30H
MOV AL,DL
SHL AL,01
SHL AL,01
SHL AL,01
SHL AL,01
MOV DL,[DI+5]
SUB DL,30H
ADD AL,DL
MOV [BX],AX
ADD BX,02
LOOP A
SORT: MOV BX, OFFSET ARRAY
MOV CX,LEN-1
MOV CHANGE, 0
GOON: MOV AX,[BX]
ADD BX,2
CMP AX,[BX]
JB NEXT
MOV CHANGE, 1
XCHG AX, [BX]
MOV [BX-2], AX
NEXT: LOOP GOON
CMP CHANGE, 0
JNE SORT
MOV CX,LEN
LEA SI,ARRAY
MOV AH,09H
LEA DX,SY
INT 21H
B :MOV AH,09H
LEA DX,ENTER
INT 21H
MOV BX,[SI]
MOV DH,BH
AND BH,0F0H
SHR BH,1
SHR BH,1
SHR BH,1
SHR BH,1
ADD BH,30H
MOV DL,BH
MOV AH,02
INT 21H
AND DH,0FH
ADD DH,30H
MOV DL,DH
MOV AH,02
INT 21H
MOV DH,BL
AND BL,0F0H
SHR BL,01
SHR BL,01
SHR BL,01
SHR BL,01
ADD BL,30H
MOV DL,BL
MOV AH,02
INT 21H
AND DH,0FH
ADD DH,30H
MOV DL,DH
MOV AH,02
INT 21H
ADD SI,2
LOOP B
MOV AX,4C00H
INT 21H
CODE ENDS
END START
程序如上 经过Uedit32调试没有问题,需要验收,详细讲解程序的思路细节,希望编程高手达人帮忙翻译一下,最好能每句翻译,说明什么意思,如果有更好更简洁的程序也可以写出来,要求一样,只要让我看懂,变成学过一点,但早已忘得差不多了,希望能详细点。分数不是问题,说清楚了加到500分,通过验收有多少加多少,最低加到1000分。有需要可以加Q:1163107480
可以编好发到邮箱[email protected]

;内容是编写由键盘输入10个4位的数据并将这些数由大到小或由小到大进行排序其结果输出在显示屏上的程序.

ASSUME CS:CODE, SS:STACK, DS:DATA

DATA SEGMENT

STR DB 0AH,0DH,"Please input a thousand number: ",0AH,0DH,'$'

BUF DB 5;缓冲区能容纳的字符个数

DB ?;系统自动存入用户从键盘输入的字符的个数(不包括回车)

DB 5 DUP (?);存放用户从键盘输入的字符的ASCII码(包括回车)

COUNT EQU 10

NUMBER DW 10 DUP (0)

MULNUMBER DW ?

CRLF DB 0AH,0DH,'$'

DATA ENDS

STACK SEGMENT

DB 16 DUP (?)

STACK ENDS

CODE SEGMENT

START:MOV AX,DATA

MOV DS,AX;设置好数据段

MOV AX,STACK

MOV SS,AX;设置好数据段

MOV SP,10H;设置好栈顶指针

MOV DI,0

MOV CX,COUNT;将10赋值给CX

INPUT:

PUSH CX;因为下面会用到CX,所以为了不覆盖CX的值,我们将CX存放在栈保存着

LEA DX,STR

MOV AH,9

INT 21H;显示提示信息

LEA DX,BUF

MOV AH,10

INT 21H;接收用户从键盘输入的信息

LEA SI,BUF+2;取BUF+2的偏移地址,然后赋值给SI,这个BUF+2的地址是存放用户输入的地址单元

MOV BX,3

;下面的程序段是将用户输入的4个字符转换成4位数(十六进制)

;TOTAL = 千位的数字*1000+百位的数字*100+十位的数字*10+个

MOV MULNUMBER,1;乘数

MOV CL,BUF+1

NEXT:XOR AX,AX

MOV AL,[SI+BX];与用户输入的4位数的个位数

SUB AL,30H;因为字符数字的ASCII码是以30H+数字,所以数字=ASCII - 30H

MUL MULNUMBER;因为4位数不超过65535,所以我们不用里DX中的值,因为只有乘出来的积打印65535,DX才会有变化

ADD NUMBER[DI],AX;将积和TOTAL相加

XOR AX,AX;AX清零

MOV AL,10

MUL MULNUMBER

MOV MULNUMBER,AX;乘数*10

DEC BX;指向高一位

LOOP NEXT

ADD DI,2;指向NUMBER的下一个字单元

POP CX;恢复原来的CX的值

LOOP INPUT;循环输入

;接下来就是排序了

;这里我们用冒泡排序,升序

;冒泡排序的思想是:从第一个元素开始,依次对N个元素中相邻的两个元素进行比较

;若顺序不满足则交换,经过一轮后,最大的元素就排到了最右边.后面依次类推

MOV CX,COUNT

DEC CX

MOV DI,0;最右边有多少个元素,一开始是0个

SEQU1:PUSH CX

MOV BX,0

MOV CX,COUNT

SUB CX,DI

SEQU2:MOV AX,NUMBER[BX];前一个元素

CMP AX,NUMBER[BX+2];后一个元素

JB SEQU3;如果前一个元素小于后一个元素,就不要交换了

;以下4句是交换NUMBER[BX+2]和NUMBER[BX]地址的值

XCHG AX,NUMBER[BX+2]

MOV DX,NUMBER[BX]

MOV NUMBER[BX+2],DX

MOV NUMBER[BX],AX

SEQU3:ADD BX,2

LOOP SEQU2

INC DI;右边有一个最大元素,DI+1

POP CX

LOOP SEQU1

;下面是将排好序的数显示出来

LEA SI,NUMBER

MOV BX,0

MOV CX,COUNT

DISPLAY:

PUSH CX;保存CX的值

MOV CX,10

XOR DX,DX

MOV AX,NUMBER[BX]

DIS1:DIV CX

PUSH DX;保存余数

XOR DX,DX;DX清零,因为做字除法的时候,(DX,AX)都会参与运算,在这里我们只需要AX运算,如果有DX运算的话,那么结果会出错

AND AX,AX;测试AL(商是否为0)

JNZ DIS1;如果不是0,说明没有除尽,继续循环

;输出回车,换行

LEA DX,CRLF

MOV AH,9

INT 21H

;现在栈里的元素是5个CX,DX,DX,DX,DX,而DX从左到有时个位,十位,百位,千位

;所以现在我们倒着输出,就可以得到千,百,十,个

MOV CL,4;四位数

DIS2:POP DX

ADD DL,30H

MOV AH,2

INT 21H

LOOP DIS2

ADD BX,2;下一个元素

POP CX

LOOP DISPLAY

MOV AX,4C00H

INT 21H

CODE ENDS 

END START


结果图:

上面还有数据没有显示,窗口限制没有办法

追问

嗯 ,回答比较靠谱,可否补充得更详细一点点呢,有些语句都忘了用法和意思,⊙﹏⊙b汗,以及应该怎么修改让输出结果变成如下格式:
please interput a nuber:
数据1 数据2 数据3 XXX XXX ……数据10
sort end output date:
依序排列的10个数
最高悬赏只能加到200 囧

追答

please  interput a nuber:

数据1  数据2  数据3 XXX XXX  ……数据10

如果在原来的程序上改成这种格式的话,那么程序的"输入程序段"和"排序程序段"需要重写.

 

 

我只改了输出而已,这个好实现

代码已发到楼主你的邮箱了

该做的注释的我都做了,有些没有注释是因为前面已经有了

有些地方只要分析一下,就会明白的.

效果图:

温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2018-03-13
DATA SEGMENT
LEN EQU 10
//定义宏 LEN=10
ARRAY DW 10 DUP(?)
//定义word型数组 ARRAY[10]
MESS DB 0DH,0AH,'PLEASE INPUT NUMBERS',0DH,0AH,'INPUT:$'
//定义字符串MESS="\r\nPLEASE INPUT NUMBERS\r\nINPUT:"
ENTER DB 0DH,0AH,'$'
//定义回车符ENTER="\r\n"
SY DB 0DH,0AH,'SORT END OUTPUT DATA :','$'
//定义字符串SY="\r\nSORT END OUTPUT DATA :"
NUMBER DB 5,0,5 DUP(?)
//定义byte型数组NUMBER={5,0,?,?,?,?,?}
CHANGE DB 0
//定义byte型变量CHANGE=0
DATA ENDS

STACK SEGMENT STACK
STA DB 64 DUP(0)
STACK_TOP DB 0
STACK ENDS
//堆栈空间64+1=65byte,STACK_TOP为栈顶
//不过好像程序里没有用到堆栈操作

CODE SEGMENT
ASSUME CS:CODE, DS:DATA , SS:STACK

START: MOV AX, DATA
MOV DS, AX
MOV AX,STACK
MOV SS,AX
//段寄存器初始化
LEA SP, STACK_TOP
//堆栈指针初始化
MOV BX, OFFSET ARRAY
//把ARRAY的偏移地址赋给BX
//即BX指向ARRAY[0]
MOV CX,LEN
设置循环次数10次
A :MOV AH,09H
LEA DX,MESS
INT 21H
//屏幕显示字符串MESS的内容
LEA DX,NUMBER
MOV AH,0AH
INT 21H
//从键盘输入东西到NUMBER
LEA DI,NUMBER
//DI指向NUMBER[0]
MOV DL,[DI+2]
//DL等于NUMBER[2]
SUB DL,30H
//DL=DL-30H
//(说明:30H就是'0',这个操作把字符转换成数字,例如'1'->1)
MOV AH,DL
SHL AH,01
SHL AH,01
SHL AH,01
SHL AH,01
//AH=DL*16
MOV DL,[DI+3]
//DL=NUMBER[3]
SUB DL,30H
//转换
ADD AH,DL
//AH=AH+DL
MOV DL,[DI+4]
//DL=NUMBER[4]
SUB DL,30H
//转换
MOV AL,DL
SHL AL,01
SHL AL,01
SHL AL,01
SHL AL,01
//AL=DL*16
MOV DL,[DI+5]
//DL=NUMBER[5]
SUB DL,30H
//转换
ADD AL,DL
//AL=AL+DL
MOV [BX],AX
//ARRAY[0]=AX
ADD BX,02
//BX=BX+2,即BX现在指向ARRAY[1]的地址
LOOP A
//循环
SORT: MOV BX, OFFSET ARRAY
//BX指向ARRAY[0]
MOV CX,LEN-1
//设置循环次数9次
MOV CHANGE, 0
//初始化CHANGE=0
GOON: MOV AX,[BX]
//AX=ARRAY[0]
ADD BX,2
//BX指向ARRAY[1]
CMP AX,[BX]
//ARRAY[0]和ARRAY[1]比较大小
JB NEXT
//如果ARRAY[0]>ARRAY[1]则不进行处理,继续下一步
MOV CHANGE, 1
//否则的话 CHANGE=1 并执行下面的代码
XCHG AX, [BX]
MOV [BX-2], AX
//交换ARRAY[0]和ARRAY[1]
//处理结束,下一步
NEXT: LOOP GOON
//循环
CMP CHANGE, 0
//CHANGE和0比较大小
JNE SORT
//如果CHANGE不等于0,则继续SORT
//SORT第一次把最小的数放在了最后
//SORT第二次把第二小的数放在了倒数第二的位置,以此类推
MOV CX,LEN
//设置循环次数10次
//排序结束,下面开始输出
LEA SI,ARRAY
//SI指向ARRAY[0]
MOV AH,09H
LEA DX,SY
INT 21H
//屏幕显示字符串SY的内容
B :MOV AH,09H
LEA DX,ENTER
INT 21H
//屏幕输出一个回车
MOV BX,[SI]
//BX=ARRAY[0]
MOV DH,BH
//DH=BH
AND BH,0F0H
//BH的低四位清零
SHR BH,1
SHR BH,1
SHR BH,1
SHR BH,1
//BH高四位转移到低四位
ADD BH,30H
//BH=BH+30H
//这个操作把数字转换成字符
MOV DL,BH
MOV AH,02
INT 21H
//输出BH,即ARRAY[0]的最高位
AND DH,0FH
ADD DH,30H
MOV DL,DH
MOV AH,02
INT 21H
//输出ARRAY[0]的次高位
MOV DH,BL
AND BL,0F0H
SHR BL,01
SHR BL,01
SHR BL,01
SHR BL,01
ADD BL,30H
MOV DL,BL
MOV AH,02
INT 21H
AND DH,0FH
ADD DH,30H
MOV DL,DH
MOV AH,02
INT 21H
//输出ARRAY[0]的后两位
ADD SI,2
//SI指向ARRAY[1]
LOOP B
//循环
MOV AX,4C00H
INT 21H
//程序结束
CODE ENDS
END START本回答被网友采纳
第2个回答  2012-12-13
DATA SEGMENT ;数据段,都这么写
LEN EQU 10 ;变量LEN=10
ARRAY DW 10 DUP(?) ;定义10个DW字类型的变量,成为一个数组ARRAY
MESS DB 0DH,0AH,'PLEASE INPUT NUMBERS',0DH,0AH,'INPUT:$';DB字节类型的变量MESS,0DH,0AH控制回车,'PLEASE INPUT NUMBERS'用来显示,0DH,0AH再回车,显示'INPUT:',$表示字符串内容结束
ENTER DB 0DH,0AH,'$';ENTER表示回车
SY DB 0DH,0AH,'SORT END OUTPUT DATA :','$';回车,打印'SORT END OUTPUT DATA :,$作用同上
NUMBER DB 5,0,5 DUP(?); 同上
CHANGE DB 0 ;变量CHANGE=0
DATA ENDS ;数据段结束

STACK SEGMENT STACK ;这是堆栈段,老师不会让你讲它,固定格式
STA DB 64 DUP(0)
STACK_TOP DB 0
STACK ENDS

CODE SEGMENT;代码段
ASSUME CS:CODE, DS:DATA , SS:STACK;这里也是固定的,不会问

太尼玛长了 我放弃咯 囧、、、追问

感谢你的回答,这程序不长啊,同一个题目,其他同学编出来3、4页,我这只有一页啊,能继续翻译完么,按惯例依然送500分- -

相似回答