以上是C語言程序 ;用匯編語言實現(xiàn)實現(xiàn)冒泡排序,并將排序后的數(shù)輸出 DATAS SEGMENT A dw 5, 5, 3, 7, 4, 2, 5, 4, 9, 1, 8, 6 N=$-A ;計算數(shù)字所占的字節(jié)數(shù) DATAS ENDS //相當于int a[] = {5, 5, 3, 7, 4, 2, 5, 4, 9, 1, 8, 6};// CODES SEGMENT ASSUME CS:CODES,DS:DATAS START:MOV AX,DATAS MOV DS,AX // 相當于int a[] 中的數(shù)組a獲得了一個確切的起始地址 MOV SI,0 ;SI遍歷數(shù)字;前一個數(shù)的地址 MOV CX,N/2-1 ;設置循環(huán)次數(shù),M(M=N/2)個數(shù)需要,循環(huán)M-1次 CALL BUBBLE ;調(diào)用BUBBLE將原來的數(shù)排序 ;輸出排序后的數(shù) MOV CX,N/2 ;循環(huán)M次輸出排序后的M個數(shù) MOV SI,0 ;SI遍歷排序后的數(shù) MOV DI,0 ;用DI記錄數(shù)字的位數(shù) MOV BP,N+5 ;BP用于遍歷存儲的轉(zhuǎn)化后的字符的位置(因為每個數(shù)字占4個字節(jié),中間一個 空格) SHOW: PUSH CX ;循環(huán)次數(shù)入棧 MOV DX,0 ;由于將要進行16位除需要置高16位為0 MOV AX,[SI] ;低16位為排序后的數(shù) CALL DTOC ;調(diào)用DTOC將十進制數(shù)轉(zhuǎn)換為字符串 CALL SHOW_STR ;調(diào)用SHOW_STR將一個數(shù)轉(zhuǎn)化得到的字符串輸出 ADD SI,2 ;下一個數(shù) POP CX ;循環(huán)次數(shù)出棧棧 LOOP SHOW MOV AH,4CH 匯編語言先要將每一個排好序的數(shù)字轉(zhuǎn)換為字符串,然后再在屏幕上顯示 INT 21H 整個上面這一段相當于for (i=0; i<12; ++i) ;冒泡排序 BUBBLE PROC L1: PUSH CX ;將循環(huán)次數(shù)入棧 LEA SI,A ;SI遍歷DATAS數(shù)據(jù)段的數(shù)字 L2: MOV AX,A[SI] ;將前一個數(shù)存于AX CMP AX,A[SI+2] ;比較前后兩個數(shù) JBE NEXT ;如果前一個數(shù)小于或等于后一個數(shù)則繼續(xù)本輪的比較 XCHG AX,A[SI+2] ;否則,交換前后兩個數(shù)的位置 MOV A[SI],AX NEXT:ADD SI,2 ;下一個數(shù) LOOP L2 ;注意內(nèi)層循環(huán)的次數(shù)已經(jīng)確定了 POP CX ;將循環(huán)次數(shù)出棧 LOOP L1 ;下一輪比較 RET BUBBLE ENDP //整個過程與C語言中的冒泡過程一樣。注意兩者的指針差別:C語言中就是簡單的整型變量 i,j,而匯編語言則要指定具體是哪個寄存器// ; 將十進制數(shù)轉(zhuǎn)換為字符串并儲存起來 DTOC PROC S:MOV CX,10 ;將除數(shù)10,放入CX中 CALL DIVDW ;調(diào)用DIVDW程序 ADD CL,30H ;把數(shù)字轉(zhuǎn)換為ASCII碼,這樣就能顯示了 MOV DS:[BP],CL ;把ASCII碼放到內(nèi)存中 INC DI ;用DI記錄循環(huán)的次數(shù) PUSH AX ;將低16位入棧 ADD AX,DX ;將高位與低位相加,接著判斷是否已經(jīng)除盡 JZ BACK ;除盡后返回調(diào)用處 POP AX ;將低16位出棧 DEC BP ;逆序存放轉(zhuǎn)化后的字符,便于主程序調(diào)用SHOW_STR JMP S BACK:POP AX ;為了得到正確的IP值,需要出棧一次 RET DTOC ENDP ;子程序定義開始,功能是分離被除數(shù)的各個位的數(shù)字 ;公式:X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N DIVDW PROC PUSH AX ;低16位入棧 MOV AX,DX ;將高16位寫入AX, MOV DX,0 ;將高16位置零 DIV CX ;將新的數(shù)除10, MOV BX,AX ;將商int(H/N)轉(zhuǎn)移到BX,默認余數(shù)rem(H/N)在DX POP AX ;將低16位出棧, DIV CX ;將[rem(H/N)*65536+L]除10,默認余數(shù)在DX MOV CX,DX ;將余數(shù)轉(zhuǎn)移到CX MOV DX,BX ;將商int(H/N)轉(zhuǎn)移到dx,相當于int(H/N)*65536 RET ;子程序定義結(jié)束 DIVDW ENDP //C語言中沒有這兩段,全部隱藏在一句簡單的printf('%d ', a[i]);之中// ;實現(xiàn)字符串的輸出 SHOW_STR PROC S2:MOV AH,2 ;輸出數(shù)字轉(zhuǎn)化后的字符串 MOV DL,DS:[BP] INT 21H INC BP ;順序輸出 DEC DI ;數(shù)字的位數(shù)減一 JZ OK ;字符串輸出完了就結(jié)束 JMP S2 ;否則繼續(xù)輸出 OK:MOV AH,2 ;輸出空格 MOV DL,0 INT 21H RET SHOW_STR ENDP //C語言中也沒有這段,同樣全部隱藏在一句簡單的printf('%d ', a[i]);之中// CODES ENDS END START 由以上對比可以看到,匯編語言中的數(shù)字、字符、變量等的地址分配細節(jié),都被高級語言隱藏了,這個過程其實也是一個程序的編譯過程;同樣數(shù)字到字符的轉(zhuǎn)換過程也被隱藏了。所以,用高級語言編寫同一個程序,就比用匯編語言要簡單得多。 |
|
|
來自: 喜歡站在山上 > 《匯編語言及內(nèi)核》