汇编语言求最值以及冒泡法进行排序

我尝试了三种,第一种方法是处理无符号数比较简单的将数据存放在数据段不进行输入,第二种是处理无符号数手动输入数据,第三种是处理有符号数据手动输入。
算法都是一样的,求最值利用的打擂台算法,排序利用的冒泡法。
首先是第一种,

DATAS SEGMENT
    ;此处输入数据段代码
    buf db 90h,20h,46h,80h,59h,78h,34h,00h,12h,88h
        db 0ffh,0a4h,04ah,07fh,035h,0c8h,0b3h,0d4h,0e3h
    count equ $-buf
    max db ?  
    min db ?
    buf2 db 'Please input ten number(0~9):',0dh,0ah,'$'
    buf3 db 0ah,'The biggest number is:',0dh,0ah,'$'
    buf4 db 0ah,'The smallest number is:',0dh,0ah,'$'
    buf5 db 0ah,'The sorted array is:',0dh,0ah,'$'
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    dw 50 dup(?)
    top label byte
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	mov ax,stacks
	mov ss,ax
	mov sp,offset top
    MOV AX,DATAS
    MOV DS,AX
    ;显示内存中所有数据
    mov cx,count
    lea bx,buf
LOOP1:
	mov al,[bx]
	CALL show_high
	call kong_ge
	inc bx
	loop loop1
	
    ;计算最大数
    mov cx,count
    lea bx,buf
    mov al,[bx]
    inc bx
    dec cx
again:
	cmp al,[bx]
	jae next
	mov al,[bx]
next:
	inc bx
	loop again
	mov max,al	
	
	;显示部分
    mov dx,offset buf3
    mov ah,9h
    int 21h    
    call show_high
	
	;计算最小数
	mov cx,count
    lea bx,buf
    mov al,[bx]
    inc bx
    dec cx
again_min:
	cmp al,[bx]
	jb next_min
	mov al,[bx]
next_min:
	inc bx
	loop again_min
	mov min,al	
	
	;显示部分
    mov dx,offset buf4
    mov ah,9h
    int 21h
    call show_high
    ;jmp end_pro
    
    mov cx,count-1;cx为比较轮数,大循环次数
loop3:
	mov dx,cx;dx表示大循环次数
	mov bx,0;地址指针
loop4:
	mov al,buf[bx]
	cmp al,buf[bx+1]
	jbe no_change
	xchg al,buf[bx+1]
	mov buf[bx],al
no_change:
	inc bx
	loop loop4
	mov cx,dx;一轮比完之后,cx再次赋值比较轮数
	loop loop3
	;提示语
	mov dx,offset buf5
    mov ah,9h
    int 21h 
    lea bx,buf
	mov cx,count
LOOP5:
	mov al,[bx]
	CALL show_high
	call kong_ge
	inc bx
	loop loop5
	jmp end_pro
    
show_high proc near;显示字节的高位
	mov dh,al
	;原先的cx要压栈
	push cx 
	mov cl,04h
	and al,0f0h
	shr al,cl
	pop cx
	cmp al,09h
	ja special1
	add al,30h
output1:
	cmp al,30h
	jz show_low
	mov dl,al
	mov ah,02h
	int 21h
show_low:;显示字节的低位
	mov al,dh
	and al,0fh
	cmp al,09h
	ja special2
	add al,30h
output2:
	mov dl,al
	mov ah,02h
	int 21h
	ret
special1:
	add al,37h
	jmp output1
special2:
	add al,37h
	jmp output2
show_high endp	

kong_ge proc near
	mov dl,' '
	mov ah,02h
	int 21h
	ret
kong_ge endp

end_pro:    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

结果
第二种方法是在第一种的基础上的改进最大的区别就是加入了输入和输出函数。我设置的输入十个数,这个可以任意修改。

DATAS SEGMENT
    ;此处输入数据段代码
    buf db 10 dup(?)
    count equ $-buf
    max db ?  
    min db ?
    buf1 db 'The original array is:',0dh,0ah,'$'
    buf2 db 'Please input ten number:',0dh,0ah,'$'
    buf3 db 0ah,'The biggest number is:',0dh,0ah,'$'
    buf4 db 0ah,'The smallest number is:',0dh,0ah,'$'
    buf5 db 0ah,'The sorted array is:',0dh,0ah,'$'
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    dw 50 dup(?)
    top label byte
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	mov ax,stacks
	mov ss,ax
	mov sp,offset top
    MOV AX,DATAS
    MOV DS,AX
    ;输入所有数据
    lea di,buf
    mov cx,count  
    mov dx,offset buf2
    mov ah,9h
    int 21h 
input_loop:
	mov bx,0
    call input
    inc di
    loop input_loop

	mov dx,offset buf1
    mov ah,9h
    int 21h 
    ;显示内存中所有数据
    mov cx,count
    lea bx,buf
LOOP1:
	mov al,[bx]
	CALL show_high
	call kong_ge
	inc bx
	loop loop1
	
    ;计算最大数
    mov cx,count
    lea bx,buf
    mov al,[bx]
    inc bx
    dec cx
again:
	cmp al,[bx]
	jae next
	mov al,[bx]
next:
	inc bx
	loop again
	mov max,al	
	
	;显示部分
    mov dx,offset buf3
    mov ah,9h
    int 21h    
    call show_high
	
	;计算最小数
	mov cx,count
    lea bx,buf
    mov al,[bx]
    inc bx
    dec cx
again_min:
	cmp al,[bx]
	jb next_min
	mov al,[bx]
next_min:
	inc bx
	loop again_min
	mov min,al	
	
	;显示部分
    mov dx,offset buf4
    mov ah,9h
    int 21h
    call show_high
    ;冒泡排序部分
     mov cx,count-1;cx为比较轮数,大循环次数
loop3:
	mov dx,cx;dx表示大循环次数
	mov bx,0;地址指针
loop4:
	mov al,buf[bx]
	cmp al,buf[bx+1]
	jbe no_change
	xchg al,buf[bx+1]
	mov buf[bx],al
no_change:
	inc bx
	loop loop4
	mov cx,dx;一轮比完之后,cx再次赋值比较轮数
	loop loop3
	;提示语
	mov dx,offset buf5
    mov ah,9h
    int 21h 
    lea bx,buf
	mov cx,count
LOOP5:
	mov al,[bx]
	CALL show_high
	call kong_ge
	inc bx
	loop loop5
	jmp end_pro
    
show_high proc near;显示字节的高位
	mov dh,al
	;原先的cx要压栈
	push cx 
	mov cl,04h
	and al,0f0h
	shr al,cl
	pop cx
	add al,30h
	cmp al,30h
	jz show_low
	mov dl,al
	mov ah,02h
	int 21h
show_low:;显示字节的低位
	mov al,dh
	and al,0fh
	add al,30h
	mov dl,al
	mov ah,02h
	int 21h
	ret
show_high endp	

kong_ge proc near
	mov dl,' '
	mov ah,02h
	int 21h
	ret
kong_ge endp

input proc near
	push cx
	mov ch,00h;用来记录输入的位数不超过两位
get_char:
	mov ah,01h
	int 21h
	inc ch;计算位数
	cmp al,0dh
	je exit
	sub al,30h
	jb exit
	cmp al,9
	ja exit	
	cmp ch,03h;超出位数
	jae exit
	xchg al,bl;bl起始时为0
	mov cl,04h
	shl al,cl	
	xchg al,bl
	add bl,al
	mov [di],bl
	jmp get_char
exit:
	pop cx
	ret
input endp

end_pro:    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

在这里插入图片描述
第三种方法,则是对有符号数进行排序,和第二种方法也是在输入和输出的方面有区别,这种方法将数据以十进制的形式保存,以十进制的形式输出,输入的思想是每次输入的字符加上上一次的结果乘以10作为这一次的结果。输出的思想是每次输出都除以十取余数,直到商为0,其次和前两种方法相比在比较方面使用的语句也有所区别。

DATAS SEGMENT
    ;此处输入数据段代码
    buf dw 10 dup(?)
    count equ ($-buf)/2
    tmp db 10 dup(?);保存数的每一位,打印的时候要用
    max dw ?  
    min dw ?
    buf1 db 'The original array is:',0dh,0ah,'$'
    buf2 db 'Please input ten number:',0dh,0ah,'$'
    buf3 db 0ah,'The biggest number is:',0dh,0ah,'$'
    buf4 db 0ah,'The smallest number is:',0dh,0ah,'$'
    buf5 db 0ah,'The sorted array is:',0dh,0ah,'$'
    buf6 db 0ah,'The character is out of range, Try again:',0dh,0ah,'$'
DATAS ENDS

STACKS SEGMENT
    ;此处输入堆栈段代码
    dw 50 dup(?)
    top label byte
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	mov ax,stacks
	mov ss,ax
	mov sp,offset top
    MOV AX,DATAS
    MOV DS,AX
    ;输入所有数据
    lea di,buf
    mov cx,count 
    mov bx,10
    mov si,0
    mov bp,0 
    mov dx,offset buf2
    mov ah,9h
    int 21h 
input_loop:
	mov dx,0
    call input
    add si,2
    inc di
    loop input_loop

	mov dx,offset buf1
    mov ah,9h
    int 21h 
    ;显示内存中所有数据
    mov cx,count
    mov si,0
LOOP1:
    mov ax,buf[si]
    call show_ascii
    add si,2     
    loop loop1

    ;计算最大数
    mov cx,count
    lea bx,buf
    mov ax,[bx]
    add bx,02h
    dec cx
again:
	cmp ax,[bx]
	jge next
	mov ax,[bx]
next:
	add bx,02h
	loop again
	mov max,ax	
	
	;显示部分
    mov dx,offset buf3
    mov ah,9h
    int 21h
    mov ax,max    
    call show_ascii
	
	;计算最小数
	mov cx,count
    lea bx,buf
    mov ax,[bx]
    add bx,02h
    dec cx
again_min:
	cmp ax,[bx]
	jl next_min
	mov ax,[bx]
next_min:
	add bx,02h
	loop again_min
	mov min,ax	
	
	;显示部分
    mov dx,offset buf4
    mov ah,9h
    int 21h
    mov ax,min
    call show_ascii
    
    ;冒泡排序部分
     mov cx,count-1;cx为比较轮数,大循环次数
loop3:
	mov dx,cx;dx表示大循环次数
	mov bx,0;地址指针
loop4:
	mov ax,buf[bx]
	cmp ax,buf[bx+2]
	jle no_change
	xchg ax,buf[bx+2]
	mov buf[bx],ax
no_change:
	add bx,02h
	loop loop4
	mov cx,dx;一轮比完之后,cx再次赋值比较轮数
	loop loop3
	;提示语
	mov dx,offset buf5
    mov ah,9h
    int 21h 
    mov si,0
	mov cx,count
LOOP5:
	mov ax,buf[si]
	CALL show_ascii
	add si,02h
	loop loop5
	jmp end_pro	

kong_ge proc near
	mov dl,' '
	mov ah,02h
	int 21h
	ret
kong_ge endp

input proc near
	push cx
	mov cx,00h
get_char:
	mov ah,01h
	int 21h
	cmp al,'-';判断是否为负数
	jz nagetive
	cmp al,0dh;判断是否为回车
	jz process_1
	cmp al,' ';判断是否为空格
	jz process_1
	cmp al,30h
	jl mistake
	cmp al,39h;大于9
	ja judge1
	jmp process_2
judge1:
	cmp al,41h;表示在39<x<41的数
	jb mistake
	cmp al,80h;表示>46即超过F的数
	ja mistake
	jmp process_2
mistake:
	mov dx,offset buf6
    mov ah,9h
    int 21h 
    jmp get_char
nagetive:
	mov bp,1;bp作为符号位
	jmp get_char
process_2:
	push ax;
	mov ax,dx
	mul bx;乘以10,以十进制存储
	mov dx,ax;数据保存在dx中
	pop ax
	sub al,30h
	mov ah,0
	add dx,ax
	jmp get_char
process_1:
	cmp bp,1
	jnz save
	neg dx;取负命令0-原数据
save:
	mov buf[si],dx;将处理好的数据存入num中去
	mov bp,0;bp位清零	
	mov dl,0dh;回车换行重新输入
	mov ah,2
	int 21h
	mov dl,0ah
	int 21h
exit:
	pop cx
	ret
input endp

show_ascii proc near
	test ax,1000h;与命令
	jz pre_show;不是负数
	push ax
	mov dl,'-';是负数的情况,先显示负号
	mov ah,02h
	int 21h
	pop ax
	neg ax
pre_show:
	mov di,0
	mov dx,0
	mov bx,10
mid_show:
	div bx;十六进制转十进制
	add dl,30h;余数部分作为结果
	mov tmp[di],dl
	inc di
	cmp ax,0;判断商是否为0,是则表示转换完成
	jz last_show
	mov dx,0;余数部分清零
	jmp mid_show
last_show:
	mov dl,tmp[di-1];dl为待输出字符的ascii码
	mov ah,2
	int 21h
	dec di
	jnz last_show
	mov dl,' ';数据之间打印空格
	mov ah,02h
	int 21h
	ret
show_ascii endp
	

end_pro:    
    MOV AH,4CH
    INT 21H
CODES ENDS
    END START

在这里插入图片描述
这是我自己做微机实验的一些整理,好多代码来自网上和课本我做了一个整理,希望能对你们有所帮助。这个题还可以在输入小数方面做进一步的改进。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值