彙編實現氣泡排序
阿新 • • 發佈:2018-12-02
1.輸入部分實現
;下面是寫入過程,各暫存器存的東西: ;AX 用於DOS呼叫,然後還用於*10,/10之後存放結果 ;BX 用於記錄存了多少個數(每個數2位元組16位) ;CX 存放SHL、SHR的移動次數(超過1要放在CL裡) ;DX 用於存放得到每個數之前的臨時值 NNUM:;先把當前數字放入記憶體,然後使BX+2,然後下一個數字的開始(到NEXT) ; MOV CL,4 ; SHR DX,CL MOV [BX],DX ADD BX,2 MOV DX,0 ;這裡要讓AL=0,DX=0,防止NEXT的第一句將數字*10對輸入的第一個字元起作用 NEXT: ;輸入下一個數字 MOV AH,1 INT 21H ;對輸入的數進行判定,看是否是空格或者回車 CMP AL,'.' ;如果是回車符號,則證明輸入完了 JZ SORTSTART ;結尾的話跳到SORT部分排序 CMP AL,' ' JZ NNUM ;如果是空格,則證明當前輸入完了,將CX裡的數字放到儲存器中去 ;對之前的數字的高位數字調整,壓縮BCD MOV CL,4 SHL DX,CL ;加入這次的個位數 SUB AL,30H ;-30H得到對應的數字 ADD DL,AL JMP NEXT ;如果不是空格,證明當前元素沒輸入完,則再次檢測輸入當前數字的下一位
2.排序部分實現
利用雙層LOOP配合堆疊段實現
;上面完成了存入資料的操作,下面是排序的操作,各暫存器的內容: ;AX 存放交換的第一個數字 ;BX 沒用到,依舊保留原來的數值,即入讀數的數量*2 ;CX 內、外迴圈的次數,內迴圈完了出棧 ;DX 沒用到 SORTSTART: MOV AX,DATA MOV DS,AX MOV AX,BX SHR AX,1 ;內容/2,得到數字個數 MOV CX,AX ;外層迴圈AX趟 ; DEC CX ;初始化次數n為總數AX-1,因為需要內迴圈迴圈執行n-1次,不然會在第一次迴圈的時候,將最後一個數和陣列以外的內容比較並交換,使得丟失資料 ;這裡是外層迴圈 FORI: PUSH CX ;儲存外層迴圈次數 ;注意到外層第1次迴圈,內迴圈執行CX-1次,外層第2次迴圈,內迴圈執行CX-2次,...控制外迴圈的cx值恰就是內層迴圈次數 MOV SI, 0 ;相當於內層迴圈時取陣列內容的指標 ;這裡是內層迴圈 FORJ: MOV AX, [SI] ;(ax)即a[j] CMP AX, [SI+2] ;a[j]與a[j+1]比較 JBE NEXTNUM ;a[j]<=a[j+1]時 ,跳到下一步NEXTNUM不交換 XCHG AX, [SI+2] ;交換 MOV [SI], AX ;最終效果是a[j]與a[j+1]交換了 ;迴圈控制和轉跳部分 NEXTNUM: ADD SI, 2 ;下一個數,j++ lOOP FORJ ;內層迴圈,使得CX--,然後再次執行,直到CX=0 POP CX ;恢復外層迴圈的CX,相當於當前的內層for(j)結束了,執行外層的fori lOOP FORI ;外層迴圈
3.實現輸出過程
單獨處理每兩個位元組的四位數字的壓縮BCD顯示,利用CH作為內迴圈的i,'$'作為外迴圈的判斷
;這裡是最後的顯示 OUT_ALL: ;為了保證最後一個數字的正確錄入,要求手動輸入最後一個數字之後,先' '後'回車' MOV DL,13 ;回車 結尾 MOV AH,2 INT 21H MOV DL,10 ;換行 MOV AH,2 INT 21H ;AH=2 單獨顯示DL的內容 MOV BYTE PTR [BX],'$';結尾加上結尾符號標誌 MOV CX,BX MOV SI,0 SHOW: MOV DL,32 ;空格 用於顯示下一個數字 MOV AH,2 INT 21H MOV BX,[SI] ADD SI,2 ;指向下一個位元組的內容 CMP BL,'$' JZ EXIT ;設定出口 MOV CL,4 ;CL是用在下面的SHL部分 MOV CH,4 ;用於內層迴圈 ;單獨處理每兩個位元組的四位數字顯示 BYTE1: MOV DX,BX AND DX,0F000H ;僅保留最高四位 SHR DH,CL ;挪到DH的低四位 MOV DL,DH ADD DL,30H ;DL存放的恰好是所需要的ASC碼 MOV AH,2 INT 21H SHL BX,CL ;將BX左移4位,把最高位讓給下個字元 DEC CH CMP CH,0 JNZ BYTE1 ;內層迴圈 JMP SHOW
4.下面是完整的程式碼:
DATA SEGMENT
BUFFER DB 20 DUP(0FFH)
;定義資料段,放入20個FFH位元組,DPU()相當於malloc(x),用於寫入資料
DATA ENDS
;使用預設堆疊段
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
;程式碼段
;設定程式碼段和資料段的段基地址
;各暫存器存的東西:
;AX 用於DOS呼叫,然後還用於*10之後存放結果
;BX 用於記錄存了多少個數(每個數2位元組16位)
;CX 用於存放得到每個數之前的臨時值
;DX 在EXIT中用作移入結束符號和換行等等,在NEXT中DL用於存放*10放到AX裡
START:
MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET BUFFER
MOV DX,0
MOV AX,0
JMP NEXT
;下面是寫入過程,各暫存器存的東西:
;AX 用於DOS呼叫,然後還用於*10,/10之後存放結果
;BX 用於記錄存了多少個數(每個數2位元組16位)
;CX 存放SHL、SHR的移動次數(超過1要放在CL裡)
;DX 用於存放得到每個數之前的臨時值
NNUM:;先把當前數字放入記憶體,然後使BX+2,然後下一個數字的開始(到NEXT)
; MOV CL,4
; SHR DX,CL
MOV [BX],DX
ADD BX,2
MOV DX,0
;這裡要讓AL=0,DX=0,防止NEXT的第一句將數字*10對輸入的第一個字元起作用
NEXT:
;輸入下一個數字
MOV AH,1
INT 21H
;對輸入的數進行判定,看是否是空格或者回車
CMP AL,'.' ;如果是回車符號,則證明輸入完了
JZ SORTSTART ;結尾的話跳到SORT部分排序
CMP AL,' '
JZ NNUM ;如果是空格,則證明當前輸入完了,將CX裡的數字放到儲存器中去
;對之前的數字的高位數字調整,壓縮BCD
MOV CL,4
SHL DX,CL
;加入這次的個位數
SUB AL,30H ;-30H得到對應的數字
ADD DL,AL
JMP NEXT ;如果不是空格,證明當前元素沒輸入完,則再次檢測輸入當前數字的下一位
;上面完成了存入資料的操作,下面是排序的操作,各暫存器的內容:
;AX 存放交換的第一個數字
;BX 沒用到,依舊保留原來的數值,即入讀數的數量*2
;CX 內、外迴圈的次數,內迴圈完了出棧
;DX 沒用到
SORTSTART:
MOV AX,DATA
MOV DS,AX
MOV AX,BX
SHR AX,1 ;內容/2,得到數字個數
MOV CX,AX ;外層迴圈AX趟
; DEC CX ;初始化次數n為總數AX-1,因為需要內迴圈迴圈執行n-1次,不然會在第一次迴圈的時候,將最後一個數和陣列以外的內容比較並交換,使得丟失資料
;這裡是外層迴圈
FORI:
PUSH CX ;儲存外層迴圈次數
;注意到外層第1次迴圈,內迴圈執行CX-1次,外層第2次迴圈,內迴圈執行CX-2次,...控制外迴圈的cx值恰就是內層迴圈次數
MOV SI, 0 ;相當於內層迴圈時取陣列內容的指標
;這裡是內層迴圈
FORJ:
MOV AX, [SI] ;(ax)即a[j]
CMP AX, [SI+2] ;a[j]與a[j+1]比較
JBE NEXTNUM ;a[j]<=a[j+1]時 ,跳到下一步NEXTNUM不交換
XCHG AX, [SI+2] ;交換
MOV [SI], AX ;最終效果是a[j]與a[j+1]交換了
;迴圈控制和轉跳部分
NEXTNUM:
ADD SI, 2 ;下一個數,j++
lOOP FORJ ;內層迴圈,使得CX--,然後再次執行,直到CX=0
POP CX ;恢復外層迴圈的CX,相當於當前的內層for(j)結束了,執行外層的fori
lOOP FORI ;外層迴圈
;這裡是最後的顯示
OUT_ALL:
;為了保證最後一個數字的正確錄入,要求手動輸入最後一個數字之後,先' '後'回車'
MOV DL,13 ;回車 結尾
MOV AH,2
INT 21H
MOV DL,10 ;換行
MOV AH,2
INT 21H ;AH=2 單獨顯示DL的內容
MOV BYTE PTR [BX],'$';結尾加上結尾符號標誌
MOV CX,BX
MOV SI,0
SHOW:
MOV DL,32 ;空格 用於顯示下一個數字
MOV AH,2
INT 21H
MOV BX,[SI]
ADD SI,2 ;指向下一個位元組的內容
CMP BL,'$'
JZ EXIT ;設定出口
MOV CL,4 ;CL是用在下面的SHL部分
MOV CH,4 ;用於內層迴圈
;單獨處理每兩個位元組的四位數字顯示
BYTE1:
MOV DX,BX
AND DX,0F000H ;僅保留最高四位
SHR DH,CL ;挪到DH的低四位
MOV DL,DH
ADD DL,30H ;DL存放的恰好是所需要的ASC碼
MOV AH,2
INT 21H
SHL BX,CL ;將BX左移4位,把最高位讓給下個字元
DEC CH
CMP CH,0
JNZ BYTE1 ;內層迴圈
JMP SHOW
EXIT:
MOV AH,4CH
INT 21H
CODE ENDS
END START