汇编版冒泡排序

☆樱花仙子☆ 提交于 2020-12-26 01:09:12

初学汇编,老师让写个冒泡排序出来,带提示语句的,于是我就写了一个。

这个程序目前只支持8个数及以内的排序,排序的数值范围最大为255。

用到的东西都很简单,只用了基本的寄存器和jmp运算。 更新补充:我自己的电脑上\n即可实现回车换行,但是有的机器不支持,需要\r\n才可以回车换行。如果测试时出现没有回车的情况,可以在对应部分的输出语句加上mov dl,13 int 21h。

DATAS SEGMENT
	;用于存放用户输入
    a1 db 0,0,0,0,0,0,0,0
    tips db "input a number:$"
    confirm db "Your input:$"
    sort_output db "After sorted:$"
    input_tip db "Input datas:$"
      
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	;程序说明
	;先输入一个8以内的数
	;输入完毕以后空格分隔,每次输入一个100以内的数
	;输入第n个数后回车即可
	;该程序按照非降序排列
    MOV AX,DATAS
    MOV DS,AX
    ;打印提示
    mov bx,offset tips
    call print_tip
    ;输入需要排序多少个数,存在cx中
    mov ah,1
    int 21h
    mov cl,al
    mov ch,0
    sub cl,48
    ;换行输入
    mov dl,10
    mov ah,2
    int 21h
    mov bx,offset input_tip
    call print_tip
    ;循环进行输入 以空格进行分开
    mov bx,offset a1
    ;入口参数是内存的位置bx和输入的数量cx
    call input
    
    mov bx,offset confirm
    call print_tip
    
    
    mov bx,offset a1
    call loop_print
    
    
    mov bx,offset sort_output
    call print_tip
    ;排序 cx中存在排序个数,bx存待排序数字的起始位置
    mov bx,offset a1
    call sort
    
    mov bx,offset a1
    call loop_print
    
    MOV AH,4CH
    INT 21H
print_tip proc
	;设置一个入口参数
	;这里设计字符串的偏移地址的首地址作为入口参数
	;用到的入口参数的寄存器为bx
	push ax
	push bx
	push dx

s:	
	mov al,ds:[bx]
	cmp al,'$'
	je e
	mov dl,al
	mov ah,2
	int 21h
	inc bx
	jmp s
e:	
	mov dl,10
    mov ah,2
    int 21h
	pop dx
	pop bx
	pop ax
	ret
print_tip endp

input proc
	push ax
	push cx
	push dx
	mov dx,0
inputs:
muladd:
    mov ah,1
    int 21h
    ;遇到空格或者回车视为一个数字
    cmp al,32
    je next
    cmp al,13
    je next
    sub al,48
    ;内存中数据移动到al,al中数据暂存到dl
    mov dl,ds:[bx]
    mov dh,al
    mov al,dl
    ;al*10+dl
    mov dl,10
    mul dl
    add al,dh
    ;al数据放回内存
    mov ds:[bx],al
    ;不是空格,接着读
    jmp muladd
    ;遇到空格,读下一个数
next:
    inc bx
    loop inputs
    pop dx
    pop cx
    pop ax
	ret
input endp


print_num proc
	push ax
	push cx
	push bx
	push dx
	;先随便给ax一个值
    ;cx作为计数器
    mov cx,0
    ;do-while循环求每一位
s:  mov bl,10
    div bl
    push ax
    inc cx
    cmp al,0
    je n
    mov ah,0
    jmp s
    ;输出
n:  pop ax
	mov dl,ah
	add dl,48
	mov ah,2
	int 21h
	loop n
	pop dx
	pop bx
	pop cx
	pop ax
	ret
print_num endp

loop_print proc
	;循环打印内存中的数据
	;入口参数为bx,即内存的偏移地址
	;无出口参数
	push ax
	push dx
	push cx
	push dx
    cal:
    mov ah,0
    mov al,ds:[bx]
    ;函数入口是ax,数据来源为内存
    call print_num
    mov dl,32
    mov ah,2
    int 21h
    inc bx
    loop cal
    mov dl,10
    mov ah,2
    int 21h
    
    pop dx
    pop cx
    pop bx
    pop ax
	ret
loop_print endp

sort proc
	push ax
	push bx
	push cx
	push dx
	push si
	push di
	;ax bx用于存内存中数据地址及比较
	;di存储数据首地址
	mov di,bx
	;dx存n-1,冒泡的第二个循环比较n-1-i的值
	mov dx,cx
	sub dx,1
sort_loop:
	;si作为计数器,用于存储i的值
	mov si,0
begins:
	;取出两个数并比较
	mov ah,ds:[bx]
	inc bx
	mov al,ds:[bx]
	cmp ah,al
	jns replace
	inc si
	cmp dx,si
	jna hh
	jmp begins
replace:
	;内存中的值进行互换
	mov ds:[bx],ah
	sub bx,1
	mov ds:[bx],al
	inc bx
	inc si
	cmp dx,si
	jna hh
	jmp begins
hh:	
	mov bx,di
	loop sort_loop
	
	pop di
	pop si
	pop dx
	pop cx
	pop bx
	pop ax
	ret
sort endp
CODES ENDS
    END START

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!