匯編語言 輸入10個(gè)數(shù)排序并輸出的實(shí)現(xiàn)
一:題目描述
在鍵盤輸入任意10個(gè)數(shù)
- 按從小到大排序后,在計(jì)算機(jī)屏幕上先輸出來。要有結(jié)果提示(字符串顯示)。
- 將10個(gè)數(shù)做累加,結(jié)果在計(jì)算機(jī)屏幕顯示累加和。
二:偽指令的定義
1.數(shù)據(jù)段
ATAS 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 | 輸入錯(cuò)誤提示 |
string_3 | 輸出原數(shù)組提示 |
string_4 | 輸出排序后數(shù)組提示 |
string_5 | 空格符 |
DATA | 緩沖區(qū)數(shù)組 |
2.堆棧段
STACKS SEGMENT DW 256 dup(?) STACKS ENDS
3.代碼段
CODES SEGMENT ASSUME CS:CODES,DS:DATAS,SS:STACKS
三:模塊分解與實(shí)現(xiàn)
1. DOS輸入10個(gè)數(shù)字
輸入10個(gè)無符號數(shù)存入緩沖區(qū),并且保證
為何輸入范圍是65536呢 一個(gè)字的最大表示范圍是
HEX | FFFF |
---|---|
DEC | 65535 |
BIN | 1111 1111 1111 1111 |
1.1 輸入函數(shù)子程序
;---------輸入函數(shù)(單數(shù)字輸入)------------ Input PROC Near push AX push BX push CX push DX ;---------輸入提示-------------- MOV BX, 0 CLC MOV DX, 0 ;----------輸入數(shù)字-------------- 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擴(kuò)展成 AX XCHG AX, BX ;保護(hù) 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 ; 輸出錯(cuò)誤提示 JMP Lp_0 L_CRLF: ; 以換行作為一個(gè)數(shù)的結(jié)束標(biāo)志 MOV DX, 0 MOV DATA[SI], BX ; POP DX POP CX POP BX POP AX RET Input ENDP
解析函數(shù)功能:
本質(zhì)類似于高精度計(jì)算,將讀入的一個(gè)串轉(zhuǎn)成數(shù)字存儲在DATA數(shù)組中
分成三大部分
- 一: 輸入提示
- 二: 錯(cuò)誤判斷及提示
- 三: 轉(zhuǎn)化為數(shù)字
L_ERROR 錯(cuò)誤處理
L_CRLF 結(jié)束處理
我們來舉一個(gè)
Register | 1 | 2 | 3 | 4 |
---|---|---|---|---|
AX | 1 | 2 | 3 | 4 |
BX | 0 | 1 | 12 | 123 |
CX | 10 | 10 | 10 | 10 |
A
最后將結(jié)果存儲在DATA數(shù)組里
2.實(shí)現(xiàn)冒泡排序
冒泡排序作為一個(gè)簡單的排序算法,時(shí)間復(fù)雜度
內(nèi)層循環(huán)很簡單,每次從頭比到尾,遇到比它小的交換就可以了。因?yàn)槭亲植僮鲾?shù),所以循環(huán)的下標(biāo)到18為結(jié)束條件。
;---------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
外層調(diào)用:每次
;----------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內(nèi)的數(shù)字,每次輸出一個(gè)數(shù)字然后在輸出一個(gè)空格
Print函數(shù):
- 利用DIV函數(shù)的特點(diǎn)——每次除10的商放在AX, 余數(shù)放入DX
- 并利用棧的 FILO(First in Last Out)的特點(diǎn)
依舊以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 |
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,余數(shù)放入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.求累加和全部累加到
;-------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.其他函數(shù)
;----換行子函數(shù)(一個(gè)數(shù)輸入完畢)------- 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 ;----------錯(cuò)誤提示------------- 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
五:代碼與運(yùn)行截圖
1,完整版代碼(在MASM運(yùn)行通過)
;-----數(shù)據(jù)段------------ 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 ;循環(huán)次數(shù) ;---------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 ;--------結(jié)束輸入,換行--------------- 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 ;/************子程序調(diào)用****************/ ;---------輸入函數(shù)(單數(shù)字輸入)------------ Input PROC Near push AX push BX push CX push DX MOV BX, 0 CLC MOV DX, 0 ;----------輸入數(shù)字-------------- 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擴(kuò)展成 AX XCHG AX, BX ;保護(hù) 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 ; 輸出錯(cuò)誤提示 JMP Lp_0 L_CRLF: ; 以換行作為一個(gè)數(shù)的結(jié)束標(biāo)志 MOV DX, 0 MOV DATA[SI], BX ; POP DX POP CX POP BX POP AX RET Input ENDP ;----換行子函數(shù)(一個(gè)數(shù)輸入完畢)------- 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 ;----------錯(cuò)誤提示------------- 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 ;---------輸出函數(shù)(單數(shù)字輸出)------------- 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,余數(shù)放入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. 正確運(yùn)行時(shí)截圖
3. 錯(cuò)誤輸入時(shí)截圖
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
匯編程序輸出“Hello world”的實(shí)現(xiàn)
這篇文章主要介紹了匯編程序輸出“Hello world”的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01純匯編實(shí)現(xiàn)打飛機(jī)小游戲的示例代碼
這篇文章主要介紹了純匯編實(shí)現(xiàn)打飛機(jī)小游戲的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01匯編語言系列之匯編實(shí)現(xiàn)各種碼制的轉(zhuǎn)換(思路詳解)
本文列出了十六進(jìn)制轉(zhuǎn)二進(jìn)制、十進(jìn)制、ASCII碼及大小寫字母轉(zhuǎn)換的代碼,對匯編語言系列之實(shí)現(xiàn)各種碼制的轉(zhuǎn)換問題感興趣的朋友跟隨小編一起看看吧2021-11-11