天天看點

彙編語言求最值以及冒泡法進行排序

我嘗試了三種,第一種方法是處理無符号數比較簡單的将資料存放在資料段不進行輸入,第二種是處理無符号數手動輸入資料,第三種是處理有符号資料手動輸入。

算法都是一樣的,求最值利用的打擂台算法,排序利用的冒泡法。

首先是第一種,

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
           
彙編語言求最值以及冒泡法進行排序

這是我自己做微機實驗的一些整理,好多代碼來自網上和課本我做了一個整理,希望能對你們有所幫助。這個題還可以在輸入小數方面做進一步的改進。

繼續閱讀