文章目錄
一:題目描述
在鍵盤輸入任意10個數
- 按從小到大排序后,在計算機屏幕上先輸出來。要有結果提示(字符串顯示)。
- 將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個無符號數存入緩沖區,並且保證
為何輸入范圍是65536呢 一個字的最大表示范圍是 其在十進制的表示下為 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
解析函數功能:
-
本質類似於高精度計算,將讀入的一個串轉成數字存儲在DATA數組中
-
分成三大部分
一: 輸入提示
二: 錯誤判斷及提示
三: 轉化為數字
-
L_ERROR 錯誤處理
-
L_CRLF 結束處理
我們來舉一個 的例子
Register 1 2 3 4 AX 1 2 3 4 BX 0 1 12 123 CX 10 10 10 10
最后將結果存儲在DATA數組里
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
外層調用:每次
;----------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函數:
- 利用DIV函數的特點——每次除10的商放在AX, 余數放入DX
- 並利用棧的 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 的余數存入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.求累加和
- 全部累加到 上直接調用 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