汇编语言实现有符号数的冒泡排序及其修进(附选择排序)

文章介绍了在学习汇编语言过程中通过实现C语言中的冒泡排序和选择排序来加深对汇编语言的理解。作者提供了未经优化和改进后的冒泡排序代码,并解释了优化思路——通过设置标志位在无交换发生时提前结束循环,提高效率。此外,还展示了选择排序的实现。文章强调了实践编程的重要性,并提醒读者不要直接抄袭,以利于自我学习和发展。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

在学习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

四、总结

我的代码水平并不高,即使实现了需要的功能,代码也十分冗余。汇编语言学习中遇到了很多困难,原因是这一门语言已经很老了,市面上的介绍也比较少,但是总算是也学会了一些皮毛。最终自己能够独立解决简单的编程问题,算是差强人意。代码仅供参考,若有不妥之处还请批评指正。(也请学弟学妹们先自己动手做一下,不要直接借鉴,对于期末考试也是有帮助的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值