1. 程式人生 > >組合語言實現簡單的氣泡排序

組合語言實現簡單的氣泡排序

        最近在學彙編,為逆向打基礎,順手寫了一個彙編實現氣泡排序的小程式,程式碼已做好註釋,有興趣的可以簡單看看。

BUF1-BUF10與BUF關係圖(BUF中的90 80 70 60......為示例資料)


ARRADSBUF與BUF1-BUF10關係圖

;定義資料段,BUF1-BUF10儲存分割後的字串
;BUF定義輸入字串緩衝區大小為255
;REAl為實際輸入的字串數
;iptstr為輸入字串儲存的位置
;ARRADSBUF為構造的陣列位置,儲存分割後的每個字串對應的緩衝區首地址
;notice和notice2位螢幕列印的提示
DATA SEGMENT
	BUF1 db 16 dup(?)
	BUF2 db 16 dup(?)
	BUF3 db 16 dup(?)
	BUF4 db 16 dup(?)
	BUF5 db 16 dup(?)
	BUF6 db 16 dup(?)
	BUF7 db 16 dup(?)
	BUF8 db 16 dup(?)
	BUF9 db 16 dup(?)
	BUF10 db 16 dup(?)
	BUF db 255
	REAL db ?
	iptstr db 255 dup(?)
	ARRADSBUF db 50 dup(?)
    notice db 'Please input 10 numbers:','$'
    notice2 db 'Sorted numbers:','$'
DATA ENDS
;定義堆疊段
SSTACK SEGMENT STACK
	   DW 64 DUP(?)
SSTACK ENDS
;定義程式碼段
CODE SEGMENT
;關聯CS,DS暫存器和程式碼段,資料段
	ASSUME CS:CODE,DS:DATA
START:     ;將資料段段地址賦值到DS
			MOV AX,DATA
	       MOV DS,AX
		   ;獲得notice偏移地址存入DX,利用中斷09H列印字串
           MOV DX,OFFSET notice
           MOV AH,09H
           INT 21H
		   ;換行
           MOV AH,02H
           MOV DL,0DH
           INT 21H
           MOV AH,02H
           MOV DL,0AH
           INT 21H
		   ;將輸入緩衝區首地址存到DX,使用中斷0AH獲取輸入並存入BUF中
		   LEA DX,BUF       
	       MOV AH,0AH
	       INT 21H
		   ;DX(輸入緩衝區首地址)入棧,因為後面進行換行需要對DL賦值
           PUSH DX
		   ;換行
           MOV AH,02H
           MOV DL,0DH
           INT 21H
           MOV AH,02H
           MOV DL,0AH
           INT 21H
		   ;DX出棧
           POP DX
		;DX賦值給BX,BX加二(輸入緩衝區第一位為緩衝區大小,第二位為實際輸入字元個數,故輸入緩衝區的首地址+2即為輸入的字串首地址)賦值給SI
		MOV BX,DX
		ADD BX,2H
	    MOV SI,BX
		;分別用將字串分割緩衝區的首地址賦值給BX並且壓棧
				LEA BX,BUF10
	    PUSH BX
				LEA BX,BUF9
	    PUSH BX
				LEA BX,BUF8
		PUSH BX
				LEA BX,BUF7
		PUSH BX
				LEA BX,BUF6
		PUSH BX
				LEA BX,BUF5
		PUSH BX
				LEA BX,BUF4
		PUSH BX
				LEA BX,BUF3
		PUSH BX
				LEA BX,BUF2
		PUSH BX
				LEA BX,BUF1
		PUSH BX
		;AH賦值00,後面用來作為緩衝區數目的計數器
	   MOV AH,00H
	   ;陣列緩衝區首地址賦值給BX
	   LEA BX,ARRADSBUF
	   
A8:	   	;當AH等於0AH(十進位制為10)時,轉移A10
		CMP AH,0AH
		JE A10
		;將字串分割緩衝區首地址退棧,賦值到DI,賦值DI到BP
		POP DI
		MOV BP,DI
		;字串分割緩衝區首地址存入ARRADSBUF(陣列緩衝區),偏移地址為16位,故之後BX+2
		MOV DS:WORD PTR [BX],DI
		ADD BX,2H
		;判斷SI位置的字元是否為空格,是則轉移A7
A6:		MOV DL,20H
		CMP DS:BYTE PTR[SI],DL
		JE A7
		;判斷SI位置是否為標誌鍵盤輸入結束的0DH,是則轉移A13
		MOV DL,0DH
		CMP DS:BYTE PTR[SI],DL
		JE A13
		;如以上判斷皆不滿足,將SI中偏移地址所對應字元按位元組賦值到DL(一個ASCII字元佔8位,即一個位元組)
		MOV DL,DS:BYTE PTR[SI]
		;將DL賦值到DI中儲存的偏移地址所對應的值(DI中儲存的是當前操作的分割字串緩衝區的首地址)
		MOV DS:BYTE PTR[DI],DL
		;SI和DI各自增1,指向輸入的字串緩衝區和分割字串緩衝區的下一字元,轉移A6
		INC SI
		INC DI
		JMP A6

;陣列緩衝區首地址送AX,BX(寫入字串分割緩衝區首地址後的陣列緩衝區末尾地址+1)送DI,BX與AX之差送AX,使用DIV進行除法運算,
;AX除以DL(02H)商送AL,送AL到CL,CX即為陣列緩衝區中存在的地址數目(通俗的講,CX代表了陣列中元素的數量),立即數FFH送BL作為排序未完成標誌,轉移A1		
A10: LEA AX,ARRADSBUF
	MOV DI,BX
	SUB BX,AX
	MOV AX,BX
	MOV DL,02H
	DIV DL
	MOV CH,00H
	MOV CL,AL
	MOV BL,0FFH
	JMP A1

;字串分割緩衝區寫入分割後字串後在其字串末尾寫入'$'表示字串結束
A7:    MOV AL,24H
	   MOV DS:[DI],AL
;DI-BP,得到分割字串緩衝區中字串長度送DX,將DX寫入字串分割緩衝區尾部(定義的分割字串緩衝區大小為16,則首地址+0FH得到末尾地址)
	   SUB DI,BP
	   MOV DX,DI
	   MOV DS:BYTE PTR[BP+0FH],DL
;SI自增1,作用是跳過空格
	   INC SI
;AH自增1,作用是表示當前字串分割緩衝區已經寫入完畢,後轉移A8
	   INC AH
	   JMP A8
;字串分割緩衝區寫入分割後字串後在其字串末尾寫入'$'表示字串結束
A13:   MOV AL,24H
	   MOV DS:[DI],AL
;DI-BP,得到分割字串緩衝區中字串長度送DX,將DX寫入字串分割緩衝區尾部(定義的分割字串緩衝區大小為16,則首地址+0FH得到末尾地址),轉移A10
	   SUB DI,BP
	   MOV DX,DI
	   MOV DS:BYTE PTR[BP+0FH],DL
	   JMP A10

;判斷未完成標誌,如BL不為FFH,則轉移A4	   
A1:	   CMP BL,0FFH
	   JNZ A4
;送00H到BL(置未完成標誌為已完成,如交換元素位置行為發生,則BL會重新在後面的語句中被置FFH(未完成))
	   MOV BL,00H
;CX減一,表徵當前氣泡排序剩餘趟數,如結果為0,轉移A4
	   SUB CX,1H
	   JZ A4
	   ;DI(寫入字串分割緩衝區首地址後的陣列緩衝區末尾地址+1),CX分別壓棧
	   PUSH DI
	   PUSH CX
;DI-2,得到寫入字串分割緩衝區首地址後的陣列緩衝區中最後一個地址(DI只需在迴圈中不斷減2即可得到陣列中每一個字串分割緩衝區地址)
A2:    SUB DI,0002H
;按字取DI所對應的值(字串分割緩衝區首地址)送BP
	   MOV BP,WORD PTR[DI]
;由於BP為字串分割緩衝區首地址,再按位元組取其對應的值得到字串分割緩衝區中數字最高位數字ASCII碼送AH
	   MOV AH,DS:BYTE PTR [BP]
;字串分割緩衝區最後一位(儲存的字串分割緩衝區中字串長度)送DH
	   MOV DH,DS:BYTE PTR[BP+0FH]
;DI(陣列中地址指標)-2,指向前一個字串分割緩衝區地址
	   SUB DI,0002H
;按字取DI對應的值(前一字串分割緩衝區地址)送SI
	   MOV SI,WORD PTR[DI]
;按位元組取SI對應的值送AL,(此時AL中為前一字串分割緩衝區中數字最高位數字ASCII碼)
	   MOV AL,DS:BYTE PTR [SI]
;前一字串分割緩衝區最後一位(儲存的前一字串分割緩衝區中字串長度)送DL
	   MOV DL,DS:BYTE PTR[SI+0FH]
;比較兩個分割字串緩衝區中字串的長度(數字位數),後大於前轉移A3
	   CMP DH,DL
	   JA A3
;比較兩個分割字串緩衝區中字串的長度(數字位數),後小於前轉移A5
	   CMP DH,DL
	   JB A5
;比較兩個分割字串緩衝區最高位數字ASCII碼,後大於前轉移A3
	   CMP AH,AL
	   JA A3
;比較兩個分割字串緩衝區最高位數字ASCII碼,後小於前轉移A5
	   CMP AH,AL
       JB A5
;處理相等的情況
;分別按位元組取BP和SI在兩個分割字串緩衝區指向的數字
A11:	MOV AH,DS:BYTE PTR [BP]
		MOV AL,DS:BYTE PTR [SI]
;比較兩數字ASCII碼,同之前
		CMP AH,AL
		JA A3
		CMP AH,AL
		JB A5
;BP,SI自增1,指向兩個分割字串緩衝區次高位數字
		INC BP
		INC SI
;轉移A11
		JMP A11

;交換兩數字對應的字串分割緩衝區在陣列緩衝區中的位置		
A5:   	PUSH WORD PTR[DI+2H]
		PUSH WORD PTR[DI]
		POP WORD PTR[DI+2H]
		POP WORD PTR[DI]
;排序未完成標誌
	   MOV BL,0FFH
;陣列緩衝區中地址指標+2,迴圈A2,繼續比較(LOOP時每執行一次A2,CX減1)
A3:    ADD DI,2H
	   LOOP A2
;CX和DI退棧,轉移A1
	   POP CX
	   POP DI
	   JMP A1

;送notice2偏移地址到DX並用中斷顯示	   
A4:        MOV DX,OFFSET notice2
           MOV AH,09H
           INT 21H
;換行
           MOV AH,02H
           MOV DL,0DH
           INT 21H
           MOV AH,02H
           MOV DL,0AH
           INT 21H
;陣列首地址送BX
		   LEA BX,ARRADSBUF
;按字取陣列中儲存的排序後的分割字串緩衝區地址,並呼叫09H中斷列印分割字串緩衝區中的字串
A12:	   MOV DX,DS:WORD PTR[BX]
           MOV AH,09H
           INT 21H
;列印完每個字串後都列印空格
		   MOV DL,20H
		   MOV AH,02H
		   INT 21H
;陣列中的地址指標加2
		   ADD BX,2H
;比較DI(陣列中元素(地址)的末尾地址+1)是否等於BX,不等轉移A12
		   CMP DI,BX			
		   JNE A12
;程式結束
           MOV AX,4C00H
           INT 21H
CODE ENDS
END START


相關推薦

組合語言實現簡單氣泡排序

        最近在學彙編,為逆向打基礎,順手寫了一個彙編實現氣泡排序的小程式,程式碼已做好註釋,有興趣的可以簡單看看。 BUF1-BUF10與BUF關係圖(BUF中的90 80 70 60......為示例資料) ARRADSBUF與BUF1-BUF10關係圖 ;定

三種簡單排序實現氣泡排序,選擇排序,插入排序

氣泡排序: public static void main(String[] args) { int[] a = {1, 7, 4, 3, 8, 2, 9, 6, 5}; for(int j = a.length; j > 0; j--

簡單 氣泡排序

主要思想: 反覆對比數列中的相鄰的元素,不符合規則就交換,直到數列符合規則的排列。比如一個數列要求升序排序,每一次遍歷比較 ,都會把最大的一個數據“浮”到頂部。 程式碼: #include<stdio.h> void jiaohuan(int*izuo,

C#~簡單氣泡排序

1.什麼是氣泡排序 冒泡就是一隊高矮不一的學生站隊,把他們放在一排有隔板的房間裡,你不知道他們的高矮,那麼用最快的方法把他們按高矮排列最快該怎麼做.那麼你只能進入第一個房間然後進入第二個房間,比較這兩

簡單氣泡排序演算法(Java)

PS:這是個人學習中的一些記錄,貼出來和大家一起交流,不妥之處,請多指教,共同進步! public class Arithmetic { public static void main(String[] args) { int[] arr = { 12, 25, 22, 3

簡單氣泡排序的寫法和兩種優化

排序,就是將原來無序和混亂的東西按照一定的規則讓其有序地排列,其也是許多工作例如查詢的準備工作。 在問題規模較小的情況下,人手工即可完成對於很多排序工作,然而問題規模過大時,使用人工就顯得力不從心,例如在1s內讓千萬級對於千萬級的數字進行排序,哪怕人動作再快,

c++實現簡單選擇排序和堆排序

接下來我們對簡單選擇排序和堆排序做詳細額介紹,排序過程中使用的資料仍和前兩節排序過程中使用的資料相同:int a[10] = {45,12,36,76,45,9,33,19,87,23}; 1、簡單選

php 簡單氣泡排序和選擇排序

<span style="font-size:18px;">//氣泡排序 $arr=array(2,1,3,6,5,4,8,7,9,15,12,16); $n=count($arr); for ($i=0; $i <$n-1; $i++) { for

Java演算法實現氣泡排序及優化

氣泡排序,是一種很簡單的排序演算法。原理就不過多介紹了,直接入手demo。 需求:輸入一組資料,用氣泡排序進行排序。 先用最直接的方法進行排序,程式碼如下: //對一組數進行氣泡排序 public class Bubble01 { public static void m

用Java實現簡單選擇排序

package ch10; /** * 簡單選擇排序 * @author songjie * */ public class SelectSort { public static <T extends Comparable> boolean sele

簡單氣泡排序的時間複雜度及其兩種優化

在我們寫一些簡單的程式中,對一組資料進行簡單的有序的排列是經常會遇到的,所以我們必須熟悉幾種基本的演算法。 而氣泡排序就是我們學習排序的基礎 氣泡排序: 形象的可以理解為:水中上升的氣泡,在上升的過程中,氣泡越來越小,不斷比較相鄰的元素,將小的往後調 我們來解決這樣一

請程式設計實現一個氣泡排序演算法?

int [] array = new int ; int temp = 0 ; for (int i = 0 ; i < array.Length - 1 ; i++) { for (int j

【scala 資料結構和演算法】Scala實現氣泡排序

主要內容: 1、氣泡排序演算法原理 2、scala實現 3、python實現 4、goland實現 氣泡排序演算法原理: 1、比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 2、對

java幾種排序簡單實現(快速排序氣泡排序,直接插入排序

package Test; import com.alibaba.fastjson.JSONObject; public class Test { static int[] arrays = new int[] { 3, 10, 11, 1, 8, 2, 9, 4 }; // index

C語言實現簡單氣泡排序

用C實現氣泡排序       常用的排序方法有氣泡排序法,選擇排序法,插入排序法以及希爾排序法等。本文著重講解如何利用C程式碼,實現氣泡排序。       首先,要了解什麼是氣泡排序。氣泡排序是常用的一種排序方法,其基本方法就是逐次比較。即一次比較兩個數,若它們的順序錯誤,

C語言簡單實現氣泡排序演算法

#include <stdio.h> #include <stdlib.h> int main() {     int i,j,t,a[10]={10,9,52,7,1,6,2

C語言實現氣泡排序簡單選擇排序

氣泡排序(Bubble Sort)的基本思想為兩兩比較相鄰記錄的關鍵字,如果反序則交換,直到沒有反序記錄為止。 其時間複雜度為O(n^2)。 簡單選擇排序(Simple Selection Sort)

簡單排序演算法之一氣泡排序----js實現

1. 演算法步驟 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。 針對所有的元素重複以上

簡單氣泡排序實現

package com.qst.hyz; class ArrayBub{private long[]a;private int nElems; public ArrayBub(int max) {a=new long[max];nElems=0; } public void insert(long value

組合語言實現氣泡排序

;氣泡排序 ;author JRH ;2011.7.10 assume ds:data data segment   a dw 1,4,2,5,7,9,6,3 data ends code segment start:      mov ax,data      mov