实验内容
使用DEBUG命令,从首址为1000H的内存区开始存放50个数,要求设计程序将这些数由小到大排序,排序后的数,仍放在该区域中。
程序流程图
实验程序
DATAS SEGMENT ;数据段代码
SORTNUM EQU 50
DISPLAY DB 'After Change','$'
CRLF DB 0AH,0DH,'$'
DATAS ENDS
EDATA SEGMENT ;ES段代码,可以不要,本程序没用到
MES DB 50 DUP(?)
EDATA ENDS
STACKS SEGMENT ;堆栈段代码
STACKS ENDS
CODES SEGMENT ;代码段代码
ASSUME CS:CODES,DS:DATAS,SS:STACKS,ES:EDATA
START:
MOV AX,DATAS
MOV DS,AX
MOV AX,EDATA ;ES段初始化
MOV ES,AX
MOV AX,1000H
MOV ES,AX
XOR BX,BX ;初始化
MOV CX,SORTNUM-1
MOV SI,1000H
L1: MOV AL,[SI+BX] ;AL:存最小数,AH:存最小数标号
MOV AH,BL ;取第一个数设为最小数
PUSH CX
MOV DX,BX
PUSH BX ;BX在L2里面当寄存器,这里入栈
L2: INC DX ;DX指向下一个角标,取数给AL
MOV BX,DX
CMP AL,[SI+BX] ;比较
JNG L3
MOV AL,[SI+BX]
MOV AH,DL
L3: LOOP L2
POP BX
MOV CH,BL
MOV CL,[SI+BX] ;CX这里没有用到,后面会出栈,这里当寄存器使用
MOV [SI+BX],AL ;CH存外循环开始数角标,CL保存外循环数
MOV BL,AH
MOV [SI+BX],CL
MOV BL,CH
INC BX
POP CX
LOOP L1
MOV AH,9
LEA DX,DISPLAY
INT 21H
MOV AH,9
LEA DX,CRLF
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START
介绍几个要用到的DEBUG命令
T 单步执行
T N 单步执行N次
G 执行所有程序,内存单元内容保留
D 1000 1010 显示1000H单元和1010H单元之间的内容
E DS:1000 从1000H单元开始,给地址单元送数
R 看寄存器内容
R CX 会显示CX单元内容,同时会回车换行弹出冒号:
0066 输入0066,这样CX单元内容就变成0066了
运行结果
实验分析
注意到开始用了两个单步执行命令T,这是因为,头两条语句操作系统会清空单元内容。倘若在这之前给单元送数的话,内容会被清空。
还有我感觉这个实验程序用的是选择排序法,并不是冒泡排序法,如果是冒泡排序法,内循环比较中会有数字交换,但是这个程序是内循环比较完毕后,把最小数单元内容和起始单元内容交换。
数字排序只能从0-7F进行比较排序,大于7F的话,可以比较,但不会排序。我设的50个存数的地址单元为字节,理应说,可以进行排序的数应为0~FFH,但实际可以排序的数范围在0至7FH。
我一开始想过用XCHG指令来进行交换,但发现XCHG 指令不能用作地址单元与地址单元间的交换。后来改变想法,程序如下:
MOV DX,0
MOV DL,AH ;AH存放了最小数的角标
MOV DI,DX
MOV AH,1000H[DI]
XCHG 1000H[BX],AH ;BX存放了外循环开始的地址
仔细思考发现,这条语句有问题。这条指令执行完,外循环起始地址单元内容赋了最小数,但是最小数单元没有赋起始地址单元内容。刚刚突然想到可以在上句最末加上一条语句。XCHG 1000H[DI],AH
可以解决这个问题。
masm软件:
链接:https://pan.baidu.com/s/1BYMLoqk1ytman3P4DffMeA
提取码:hmf2