汇编语言冒泡排序

assume cs:code, ds:data, ss:stack

stack segment  stack
    dw 100H dup (?)
stack ends

data segment
    dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;初始化数组,最大存储20个数,最后一位为数组大小位
    tip0 db 13,10,'Please input the total number you want to sort:$';提示读入排序的数字个数
    tip1 db 13,10,'Please input the numbers (separated by space):$';提示用户输入数字
    tip2 db 13,10,'Error! Please input the number between 0 and 99!$';若用户输入的数字不在0-99范围内,显示出错消息并退出
    tip3 db 13,10,'Error! Please input the total number between 0 and 20!$';若用户输入的数字总数不在0-20范围内,显示出错消息并退出
    tip4 db 13,10,'The sort result is:$';输出最终排序结果
data ends

code segment
;主程序部分---------------------------------------------------------------------------------

start: 
    mov ax, data
    mov ds, ax;准备工作,ds段指向data

    call total;调用读入数字总数的子程序
    call input;调用读入用户输入的数字的子程序
    call bubble;调用冒泡排序子程序
    call result;调用显示排序结果的子程序
    call exit;调用程序运行完退出程序的子程序

;子程序部分-----------------------------------------------------------------------------------
    
    ;total读入数字总数------------------------------------------------------------------------
    total:
        lea dx,tip0
        call dosoutstr;调用子程序dosoutstr提示读入排序的数字个数

        mov si,40;指示指针到数组的最后一位,准备读入数字总数

        call readtwo;调用子程序readtwo读取两位数
        
        mov ax,20
        cmp ax,[si]
        jl errort;判断输入数字是否小于20,不符合条件调用子程序errort,打印出错信息并退出

        mov ax,0
        cmp ax,[si]
        jg errort;判断输入数字是否大于0,不符合条件调用子程序errort,打印出错信息并退出
    ret

        ;errort错误消息------------------------------------------------------------------------
        errort:
            lea dx,tip3
            call dosoutstr
            call exit
        ret
        ;errort结束------------------------------------------------------------------------

    ;total结束-------------------------------------------------------------------------------

    ;input读入用户输入的数字------------------------------------------------------------------
    input:
        lea dx,tip1
        call dosoutstr;打印提示消息,提示用户输入排序的数字

        mov cx,[si];通过[si]中的总数设置循环次数
        mov si,0;si回到数组起始点,准备读入数据

        ;inputr开始循环------------------------------------------------------------------------
        inputr:
            push cx;保存循环总数

            call readtwo;调用子程序readtwo读取两位数

            mov ax,99
            cmp ax,[si]
            jl error;判断输入数字是否小于99,不符合条件调用子程序error,打印出错信息并退出

            mov ax,0
            cmp ax,[si]
            jg error;判断输入数字是否大于0,不符合条件调用子程序error,打印出错信息并退出

            call dosinput;调用子程序dosinput吸收空格符号

            add si,2;si指向数组的下一个元素
            pop cx;恢复循环总数

        loop inputr;循环操作
        ;inputr结束------------------------------------------------------------------------

    ret

        ;error错误消息---------------------------------------------------------------------
        error:
            lea dx,tip2
            call dosoutstr
            call exit
        ret
        ;error结束----------------------------------------------------------------------

    ;input结束------------------------------------------------------------------------

    ;bubble对数组元素进行冒泡排序---------------------------------------------------------
    bubble:
        mov si,40;指示指针到数组的最后一位,准备提取数字总数

        mov cx,[si];通过[si]中的总数设置循环次数
        sub cx,1;循环次数减1

        ;sort排序循环----------------------------------------------------------------------
        sort:  
            push cx;保存外层循环次数,控制外循环的cx值恰就是内层循环次数
            mov si,0;指向数组第一个元素,相当于内层循环时j=0

            ;inn内层循环----------------------------------------------------------------------
            inn: 
                mov ax,[si]
                cmp ax,[si+2];[si][si+2]比较

                jbe jumpswap;[si]<=[si+2]时不交换,跳转到jumpswap子程序
                xchg ax,[si+2];[si]>[si+2]时交换

                mov [si],ax;最终[si][si+2]交换完成
                
                ;jumpswap跳过交换-------------------------------------------------------------
                jumpswap: 
                    add si,2;不交换数字,直接进入下一次判断
                ;jumpswap结束------------------------------------------------------------------

            loop inn;内层循环
            ;inn内层循环结束-----------------------------------------------------------------

            pop cx;恢复外层循环的cx

        loop sort;外层循环
        ;sort结束----------------------------------------------------------------------

    ret
    ;bubble结束------------------------------------------------------------------------
    
    ;result输出排序结果-----------------------------------------------------------------
    result:
        lea dx,tip4
        call dosoutstr;调用子程序dosoutstr提示输入排序结果

        mov si,40;指示指针到数组的最后一位,准备提取数字总数
        mov cx,[si];通过[si]中的总数设置循环次数

        mov si,0;指向数组第一个元素

        mov bl,10;借助bl获得商和余数,从而获得完整的两位数

        ;resulto遍历数组中的所有元素并输出---------------------------------------------
        resulto:
            push cx;保存循环总数

            mov ax,[si];ax获得数组中的数
            div bl;al获得商,ah获得余数

            mov dl,al;al的商送到dl中准备输出
            add dl,30h;将ASCII码转换为十进制

            mov dh,ah;将ah中的余数暂存在dh中,防止dos中断时数据丢失

            call dosoutput;调用子程序dosoutput输出dl中的商,即为输出两位数中的高位数

            mov dl,dh;dh中的商送到dl中准备输出
            add dl,30h;将ASCII码转换为十进制

            call dosoutput;调用子程序dosoutput输出dl中的余数,即为输出两位数中的低位数

            mov dl,0h
            call dosoutput;调用子程序dosoutput输出一个空格

            add si,2;指针指向下一个元素
            pop cx;恢复循环次数

        loop resulto;循环操作
        ;resulto结束---------------------------------------------

    ret
    ;result结束-----------------------------------------------------------------

    ;exit程序运行结束退出
    exit:
        mov ax, 4c00h
        int 21h;退出程序
    ;exit结束-----------------------------------------------------------------------

    ;通用辅助子程序-----------------------------------------------------------------

        ;dosinput输入字符
        dosinput:
            mov ah,01h
            int 21h
        ret

        ;dosoutput输出字符
        dosoutput:
            mov ah,02h
            int 21h
        ret

        ;dosoutstr输出字符串
        dosoutstr:
            mov ah,09h
            int 21h
        ret

        ;readtwo读取两位数
        readtwo:
            mov bl,10;借助bl与读入的数字相乘,获得高位数

            call dosinput;调用子程序dosinput读入高位数
                
            sub al,30h;将ASCII码转换为十进制
            mul bl;高位数乘10
            mov [si],ax;将高位数送入数组

            call dosinput;调用子程序dosinput读入低位数

            sub al,30h;将ASCII码转换为十进制
            add [si],al;将低位数送入数组
        ret
    ;通用辅助子程序结束-------------------------------------------------------

;主程序部分结束----------------------------------------------------------------
code ends

end start
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!汇编语言是一种低级语言,用于在计算机硬件上直接执行代码。冒泡排序是一种简单的排序算法,它通过重复地比较相邻的元素并交换它们的位置来工作。 以下是一个使用汇编语言实现冒泡排序的简单示例程序: ```assembly ; 冒泡排序程序 section .data arr db 5, 3, 8, 2, 7, 4 ; 要排序的数组 len equ $-arr ; 数组长度 section .text global _start _start: ; 冒泡排序开始 mov ecx, len ; 循环计数器 dec ecx ; 因为数组长度减一后为0,所以需要减一 outer_loop: mov esi, arr ; 指向数组的第一个元素 mov edi, arr + 1 ; 指向下一个元素 inner_loop: cmp byte [esi], [edi] ; 比较两个元素的大小 jle next ; 如果相等,跳转到下一个元素 xchg [esi], [edi] ; 交换两个元素的位置 mov edi, esi ; 将指向下一个元素的指针移动到edi next: loop inner_loop ; 循环继续,直到遍历完整个数组 dec ecx ; 计数器减一,准备下一次循环 jnz outer_loop ; 如果计数器不为零,则继续循环 ; 排序完成,程序退出 mov eax, 1 ; 系统调用号(sys_exit) xor ebx, ebx ; 退出状态码(0) int 0x80 ; 调用内核处理程序 ``` 这个程序使用x86架构的汇编语言编写,它通过外层循环和内层循环来比较和交换数组中的元素,从而实现冒泡排序。在每次外层循环中,内层循环会遍历数组中的相邻元素,并比较它们的大小。如果两个元素不相等,则交换它们的位置。通过重复这个过程,较小的元素会被逐渐“冒泡”到数组的末尾。最终,整个数组就会被排序。 请注意,这只是一个简单的示例程序,用于说明冒泡排序的基本原理。在实际应用中,可能需要更多的代码和优化来提高性能和可读性。此外,这个程序使用系统调用来退出,因此需要在Linux或类Unix系统上运行。如果你在其他操作系统上编译和运行汇编语言程序,可能会有所不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值