一、前言
在学习C语言的过程中,各类排序法,如冒泡排序、选择排序、快速排序等等都是大家熟知的知识。学习汇编语言的过程中,通过实现各类排序法,有助于我们更加熟悉汇编语言的特点,从而掌握汇编语言编程的基本步骤。
二、实验设备(环境)及要求
设备:个人电脑,windows系统下模拟dos环境
硬盘:D盘 275.69GB(基本数据分区)状态良好
64位操作系统,基于x64的处理器,windows系统为x64的处理器
Dos系统:版本号dosbox0.74,汇编工具有masm,link,debug,edit
要求:在以BUF为首址的字存储区中存放有N个有符号数,现需将它们按大到小的顺序排列在BUF存储区中,试编写其程序。要求:
i N的数目自己定义,但不要超过20
ii 要写出编程的思路并画出流程图
iii 在程序中使用标志位进行程序的优化
三、实验内容及步骤
未经优化的代码如下:
DATA SEGMENT
BUF DW 0,1,2
N=($-BUF)/2
DATA ENDS
STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
MOV CX,N
DEC CX
LOOP1:MOV DX,CX
MOV BX,0
LOOP2:MOV AX,BUF[BX]
CMP AX,BUF[BX+2]
JGE L
XCHG AX,BUF[BX+2]
MOV BUF[BX],AX
L: ADD BX,2
DEC CX
JNE LOOP2
MOV CX,DX
LOOP LOOP1
MOV AH,4CH
INT 21H
CODE ENDS
END START
基本思路不再赘述;
改进后的代码如下:
DATA SEGMENT
BUF DW 3,2,1,0
N=($-BUF)/2
DATA ENDS
STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
MOV CX,N
DEC CX
LOOP1:
MOV DX,CX
MOV BX,0
MOV SI, 0 ; 初始化标志位为0
LOOP2:
MOV AX,BUF[BX]
CMP AX,BUF[BX+2]
JGE L
XCHG AX,BUF[BX+2]
MOV BUF[BX],AX
MOV SI, 1 ; 标志位设为1,表示发生了交换
L:
ADD BX,2
DEC CX
JNE LOOP2
CMP SI, 0 ; 判断标志位是否为0
JE FINISH ;如果标志位为0,说明数组已经排好序,可以直接退出
MOV CX,DX
LOOP LOOP1
FINISH:
MOV AH,4CH
INT 21H
CODE ENDS
END START
改进解释:
冒泡排序的问题在于,即使已经在中途排好了序,它还是会依照内外两层循环继续走下去,所以想要优化这个流程。我们需要在不再发生交换时提前结束循环。也即这个标志位初始应该为0,如果它在内层循环结束时依旧为0,那么数组已经排好序,无需继续循环,提高了效率。这里我使用了3,2,1,0作为检验,这是一个无需排序的数组,所以应当会在第一次遍历结束后直接退出
三、选择排序
具体原理不再赘述
DATA SEGMENT
BUF DW 0,1,2,3
N=($-BUF)/2
DATA ENDS
STACK SEGMENT STACK
DB 200 DUP(0)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START:
MOV AX,DATA
MOV DS,AX
MOV CX,N
DEC CX
MOV BX,-2
MOV BP,0;记录第一个数的下标
LOOP1:MOV DI,CX;将计数器的值保存在DI中
ADD BX,2
MOV SI,0
LOOP2:MOV AX,BUF[BX]
MOV DX,BUF[BX]
CMP DX,BUF[BX+2];将当前数与下一个数比较
JGE L
MOV SI,BX
INC SI
INC SI ;记录下标
L: ADD BX,2
DEC CX
JNE LOOP2
MOV CX,DI;返回外层计数值,即循环次数
MOV DX,BUF[SI]
MOV BX,BUF[BP]
MOV BUF[SI],BX
MOV BUF[BP],DX;将最大数与第一个数交换
INC BP
INC BP
MOV DX,0
LOOP LOOP1
MOV AH,4CH
INT 21H
CODE ENDS
END START
四、总结
我的代码水平并不高,即使实现了需要的功能,代码也十分冗余。汇编语言学习中遇到了很多困难,原因是这一门语言已经很老了,市面上的介绍也比较少,但是总算是也学会了一些皮毛。最终自己能够独立解决简单的编程问题,算是差强人意。代码仅供参考,若有不妥之处还请批评指正。(也请学弟学妹们先自己动手做一下,不要直接借鉴,对于期末考试也是有帮助的)