;内容是编写由键盘输入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
结果图:
上面还有数据没有显示,窗口限制没有办法
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
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;这里也是固定的,不会问
太尼玛长了 我放弃咯 囧、、、