匯編語言:輸入10個數排序並輸出


一:題目描述

在鍵盤輸入任意10個數

  1. 按從小到大排序后,在計算機屏幕上先輸出來。要有結果提示(字符串顯示)。
  2. 將10個數做累加,結果在計算機屏幕顯示累加和。

二:偽指令的定義

1.數據段

DATAS SEGMENT
    string_1 DB 'Please input a numbers(0-65536):','$'
    string_2 DB 'ERROR: OVERFLOW! Please input again:','$'
    string_3 DB 'The array you have input is:',0ah,0dh,'$'
    string_4 DB 'After Sort the num is:',0ah,0dh,'$'
    string_5 DB ' ','$'
    DATA  DW 10 DUP(?)  
    massege  DB 'The sum of the array is: ',0ah,0DH,'$'   
DATAS ENDS

說明

string_1 輸入范圍提示
string_2 輸入錯誤提示
string_3 輸出原數組提示
string_4 輸出排序后數組提示
string_5 空格符
DATA 緩沖區數組

2.堆棧段

STACKS SEGMENT
    DW 256 dup(?)
STACKS ENDS

3.代碼段

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS

三:模塊分解與實現

1. DOS輸入10個數字

  • 輸入10個無符號數存入緩沖區,並且保證 n u m < 65536 num < 65536

為何輸入范圍是65536呢 一個字的最大表示范圍是 F F F F FFFF 其在十進制的表示下為 65535

HEX FFFF
DEC 65535
BIN 1111 1111 1111 1111

1.1 輸入函數子程序

;---------輸入函數(單數字輸入)------------
Input PROC Near
    push AX
    push BX
    push CX
    push DX
;---------輸入提示--------------

    MOV BX, 0
    CLC
    MOV DX, 0
;----------輸入數字--------------
    Lp_0:
        MOV AH, 1
        INT 21H
        CMP AL, 20H ;回車
        JE L_CRLF

;-----   x belong to [0,9]   ----------        
        SUB AL, 30H ; ASCII -> int
        JL L_ERROR  
        CMP AL, 9
        JG L_ERROR
;-------  string -> int   -----------
        MOV AH, 0   ;將 AL擴展成 AX
        XCHG AX, BX ;保護 AX值
        MOV CX, 10
        MUL CX      ; bx *= 10
        ADD AX , BX
        JC L_ERROR  ; OVERFLOW處理
        XCHG AX, BX 
        JMP Lp_0
    L_ERROR:
        MOV DX, 0
        MOV BX, 0
        CALL CRLF   ; 換行        
        CALL ERROR  ; 輸出錯誤提示
        JMP Lp_0
    L_CRLF:         ; 以換行作為一個數的結束標志
        MOV DX, 0
        MOV DATA[SI], BX ;
        POP DX
        POP CX
        POP BX
        POP AX
        RET
        Input ENDP

解析函數功能:

  1. 本質類似於高精度計算,將讀入的一個串轉成數字存儲在DATA數組中

  2. 分成三大部分

    一: 輸入提示

    二: 錯誤判斷及提示

    三: 轉化為數字

  3. L_ERROR 錯誤處理

  4. L_CRLF 結束處理

我們來舉一個 1234 1234 的例子

Register 1 2 3 4
AX 1 2 3 4
BX 0 1 12 123
CX 10 10 10 10

A X + ( B X C X ) AX + (BX * CX)

最后將結果存儲在DATA數組里

2.實現冒泡排序

冒泡排序作為一個簡單的排序算法,時間復雜度 O ( n 2 ) O(n^2) 需要兩層循環,為了提高代碼的可讀性,我們將內層的循環寫成一個子程序每次調用

內層循環很簡單,每次從頭比到尾,遇到比它小的交換就可以了。因為是字操作數,所以循環的下標到18為結束條件。

;---------Bubble_sort--------------------
Bubble_sort PROC NEAR
    PUSH BX
    PUSH DX
    MOV  SI,DI
LOOP1:
    ADD  SI,2  
    MOV  BX,DATA[DI]
    CMP  BX,DATA[SI]
    JA   SWAP
    JMP  NEXT
SWAP:    
    MOV  DX,DATA[SI]
    MOV  DATA[DI],DX
    MOV  DATA[SI],BX 
NEXT:
    CMP SI,18
    JL   LOOP1
    POP  DX
    POP  BX
    RET
    Bubble_sort ENDP 

外層調用:每次 D I + 2 DI + 2

;----------Sort-----------
    MOV CX, 9
    MOV DI, 0
    
FOR1:
    CALL Bubble_sort
    ADD DI, 2
    LOOP FOR1

3.DOS輸出到屏幕

    CALL CRLF
    MOV DX, OFFSET string_4 ;'After Sort the num is:'
    MOV AH, 9
    INT 21H

    MOV CX, 10
    MOV DI, 0
FOR2:
    CALL Print
    CALL Space
    ADD DI , 2
    LOOP FOR2
    CALL CRLF

輸出DATA內的數字,每次輸出一個數字然后在輸出一個空格

Print函數:

  1. 利用DIV函數的特點——每次除10的商放在AX, 余數放入DX
  2. 並利用棧的 FILO(First in Last Out)的特點

依舊以1234的例子來看一下是怎么處理的

DATA[Num] 1234 123 12 1
DX 4 3 2 1
Stack(PUSH DX) 4 4,3 4,3,2 4,3,2,1
Print(POP DX) 4 34 234 1234

D A T A [ N u m ] / 10 DATA[Num] / 10 的余數存入DX

Print PROC Near
    PUSH AX
    PUSH BX
	PUSH CX
	PUSH DX 

    MOV CX, 0
    MOV BX, 10
    MOV AX, DATA[DI]
    LAST:
        MOV DX, 0
        DIV BX ; DIV商放AX,余數放入DX
        PUSH DX
        INC CX
        CMP AX, 0
        JNZ LAST
    AGE:
        POP DX
        OR DX, 30H
        MOV AH, 2
        INT 21H
        LOOP AGE
        POP  DX
        POP  CX
	    POP  BX
	    POP  AX
	    RET
        Print ENDP

4.求累加和

  • 全部累加到 D A T A [ 0 ] DATA[0] 上直接調用 Print 函數,因為Print函數是針對DATA數組設計的,所以把最后的結果存入DATA數組中不需要額外的輸出函數。
;-------SUM-------------
Get_sum PROC NEAR
    PUSH BX
    PUSH CX

    MOV BX, 0
    MOV CX , 9
    MOV DI, 2
LOP1:
    MOV BX, DATA[0]
    ADD BX, DATA[DI]
    MOV DATA[0], BX
    ADD DI , 2
    LOOP LOP1
    POP CX
    POP BX
    RET
    Get_sum ENDP

5.其他函數

;----換行子函數(一個數輸入完畢)-------
CRLF PROC Near
    push AX
    push DX
    MOV DL, 0ah
    MOV AH, 2
    INT 21H
    pop DX
    pop AX
    RET
    CRLF ENDP
;---------空格-----------
Space PROC Near
    push AX
    push DX
    MOV DX, OFFSET string_5 ;' '
    MOV AH, 9
    INT 21H
    pop DX
    pop AX
    RET 
    Space ENDP
;----------錯誤提示-------------
ERROR PROC Near
    push BX
    push DX
    MOV DX, OFFSET string_2 ; ERROR: OVERFLOW! Please input again:
    MOV AH, 9
    INT 21H
    pop DX
    pop BX
    RET
    ERROR ENDP

四:流程圖

1. 總體流程圖

在這里插入圖片描述

2. 子程序流程圖

2.1 Input

在這里插入圖片描述

2.2 Print

在這里插入圖片描述

2.3 Bubble_Sort

在這里插入圖片描述

2.4 Get_Sum

在這里插入圖片描述

五:代碼與運行截圖

1,完整版代碼(在MASM運行通過)

;-----數據段------------
DATAS SEGMENT
    string_1 DB 'Please input 10 numbers(0-65536):','$'
    string_2 DB 'ERROR: OVERFLOW! Please input again:','$'
    string_3 DB 'The array you have input is:',0ah,0dh,'$'
    string_4 DB 'After Sort the num is:',0ah,0dh,'$'
    string_5 DB ' ','$'
    DATA  DW 10 DUP(?)  
    massege  DB 'The sum of the array is: ',0ah,0DH,'$'   
DATAS ENDS

;-----堆棧段------------
STACKS SEGMENT
    DW 256 dup(?)
STACKS ENDS

;-----代碼段------------
CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS


;-----------程序開始------------
START:
    MOV AX,DATAS
    MOV DS,AX
    MOV SI, 0  ;指針初始化
    MOV CX, 10 ;循環次數
;---------Input----------
    MOV DX, OFFSET string_1 ;Please input 10 numbers(0-65536)
    MOV AH, 9
    INT 21H
Lp:
    CALL Input
    ADD SI, 2
    Loop Lp
;--------結束輸入,換行---------------
    CALL CRLF
    MOV DX, OFFSET string_3 ;'The array you have input is:'
    MOV AH, 9               ;首地址 DS:DX 
    INT 21H
 ;-------輸出 ----------------   
    MOV CX, 10
    MOV DI, 0
Again:
    CALL Print
    CALL Space
    ADD DI , 2
    Loop Again
;/******************************/
;----------Sort-----------
    MOV CX, 9
    MOV DI, 0
    
FOR1:
    CALL Sort
    ADD DI, 2
    LOOP FOR1

    CALL CRLF
    MOV DX, OFFSET string_4 ;'After Sort the num is:'
    MOV AH, 9
    INT 21H

    MOV CX, 10
    MOV DI, 0
FOR2:
    CALL Print
    CALL Space
    ADD DI , 2
    LOOP FOR2
    CALL CRLF
;-------求和輸出---------------------    
    MOV DX, OFFSET massege;
    MOV AH, 9
    INT 21H

    CALL Get_sum
    MOV DI, 0
    CALL Print


EXIT:
    MOV AH, 4CH
    INT 21H


;/************子程序調用****************/


;---------輸入函數(單數字輸入)------------
Input PROC Near
    push AX
    push BX
    push CX
    push DX


    MOV BX, 0
    CLC
    MOV DX, 0
;----------輸入數字--------------
    Lp_0:
        MOV AH, 1
        INT 21H
        CMP AL, 20H ;空格
        JE L_CRLF

;-----   x belong to [0,9]   ----------        
        SUB AL, 30H ; ASCII -> int
        JL L_ERROR  
        CMP AL, 9
        JG L_ERROR
;-------  string -> int   -----------
        MOV AH, 0   ;將 AL擴展成 AX
        XCHG AX, BX ;保護 AX值
        MOV CX, 10
        MUL CX      ; bx *= 10
        ADD AX , BX
        JC L_ERROR  ; OVERFLOW處理
        XCHG AX, BX 
        JMP Lp_0
    L_ERROR:
        MOV DX, 0
        MOV BX, 0
        CALL CRLF   ; 換行        
        CALL ERROR  ; 輸出錯誤提示
        JMP Lp_0
    L_CRLF:         ; 以換行作為一個數的結束標志
        MOV DX, 0
        MOV DATA[SI], BX ;
        POP DX
        POP CX
        POP BX
        POP AX
        RET
        Input ENDP


;----換行子函數(一個數輸入完畢)-------
CRLF PROC Near
    push AX
    push DX
    MOV DL, 0ah
    MOV AH, 2
    INT 21H
    pop DX
    pop AX
    RET
    CRLF ENDP
;---------空格-----------
Space PROC Near
    push AX
    push DX
    MOV DX, OFFSET string_5 ;' '
    MOV AH, 9
    INT 21H
    pop DX
    pop AX
    RET 
    Space ENDP
;----------錯誤提示-------------
ERROR PROC Near
    push BX
    push DX
    MOV DX, OFFSET string_2 ; ERROR: OVERFLOW! Please input again:
    MOV AH, 9
    INT 21H
    pop DX
    pop BX
    RET
    ERROR ENDP

;---------輸出函數(單數字輸出)-------------
Print PROC Near
    PUSH AX
    PUSH BX
	PUSH CX
	PUSH DX 

    MOV CX, 0
    MOV BX, 10
    MOV AX, DATA[DI]
    LAST:
        MOV DX, 0
        DIV BX ; DIV商放AX,余數放入DX
        PUSH DX
        INC CX
        CMP AX, 0
        JNZ LAST
    AGE:
        POP DX
        OR DX, 30H
        MOV AH, 2
        INT 21H
        LOOP AGE
        POP  DX
        POP  CX
	    POP  BX
	    POP  AX
	    RET
        Print ENDP

;---------SORT---------------------
SORT PROC NEAR
    PUSH BX
    PUSH DX
    MOV  SI,DI
LOOP1:
    ADD  SI,2  
    MOV  BX,DATA[DI]
    CMP  BX,DATA[SI]
    JA   CHANGE
    JMP  NEXT
CHANGE:    
    MOV  DX,DATA[SI]
    MOV  DATA[DI],DX
    MOV  DATA[SI],BX 
NEXT:
    CMP SI,18
    JL   LOOP1
    POP  DX
    POP  BX
    RET
    SORT ENDP   
;-------SUM-------------
Get_sum PROC NEAR
    PUSH BX
    PUSH CX

    MOV BX, 0
    MOV CX , 9
    MOV DI, 2
LOP1:
    MOV BX, DATA[0]
    ADD BX, DATA[DI]
    MOV DATA[0], BX
    ADD DI , 2
    LOOP LOP1
    POP CX
    POP BX
    RET
    Get_sum ENDP

CODES ENDS
    END START

2. 正確運行時截圖

在這里插入圖片描述

3. 錯誤輸入時截圖

在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM