我嘗試了三種,第一種方法是處理無符号數比較簡單的将資料存放在資料段不進行輸入,第二種是處理無符号數手動輸入資料,第三種是處理有符号資料手動輸入。
算法都是一樣的,求最值利用的打擂台算法,排序利用的冒泡法。
首先是第一種,
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
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1ATM0EDNwgTM4IjNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
第二種方法是在第一種的基礎上的改進最大的差別就是加入了輸入和輸出函數。我設定的輸入十個數,這個可以任意修改。
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
這是我自己做微機實驗的一些整理,好多代碼來自網上和課本我做了一個整理,希望能對你們有所幫助。這個題還可以在輸入小數方面做進一步的改進。