程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 更多關於編程 >> 匯編言語超稀釋教程

匯編言語超稀釋教程

編輯:更多關於編程

匯編言語超稀釋教程。本站提示廣大學習愛好者:(匯編言語超稀釋教程)文章只能為提供參考,不一定能成為您想要的結果。以下是匯編言語超稀釋教程正文


所以我團體看法學匯編,不一定要寫順序,寫順序的確不是匯編的強項,大家無妨玩玩DEBUG,有時CRACK出一個小軟件比完成一個順序更有成就感(好像學電腦先玩游戲一樣)。某些深邃的指令現實上只對有經歷的匯編順序員有用,對我們而言,太過深邃了。為了使學習匯編言語有個好的開端,你必需要先掃除那些華美復雜的命令,將留意力集中在最重要的幾個指令上(CMP LOOP MOV JNZ……)。但是想在啰裡吧嗦的教科書中完成上述目的,談何容易,所以自己整理了這篇超稀釋(用WINZIP、WINRAR…順次壓搾,嘿嘿!)教程。大言不慚的說,看通本文,你完全可以“不經意”間在長輩或是後生賣弄一下DEBUG,很有成就感的,試試看!那麼――這個接上去呢?―― Here we go!(閱讀時看不懂不要緊,下文必有分解)

  由於匯編是經過CPU和內存跟硬件對話的,所以我們不得不先理解一下CPU和內存:(關於數的進制問題在此不提)

  CPU是可以執行電腦一切算術╱邏輯運算與根本 I/O 控制功用的一塊芯片。一種匯編言語只能用於特定的CPU。也就是說,不同的CPU其匯編言語的指令語法亦不相反。團體電腦由1981年推出至今,其CPU開展進程為:8086→80286→80386→80486→PENTIUM →……,還有AMD、CYRIX等旁支。前面兼容後面CPU的功用,只不過多了些指令(如多能奔騰的MMX指令集)、增大了存放器(如386的32位EAX)、增多了存放器(如486的FS)。為確保匯編順序可以適用於各種機型,所以引薦運用8086匯編言語,其兼容性最佳。本文所提均為8086匯編言語。存放器(Register)是CPU外部的元件,所以在存放器之間的數據傳送十分快。用處:1.可將存放器內的數據執行算術及邏輯運算。2.存於存放器內的地址可用來指向內存的某個地位,即尋址。3.可以用來讀寫數據到電腦的周邊設備。8086 有8個8位數據存放器,這些8位存放器可辨別組成16位存放器:AH&AL=AX:累加存放器,常用於運算;BH&BL=BX:基址存放器,常用於地址索引;CH&CL=CX:計數存放器,常用於計數;DH&DL=DX:數據存放器,常用於數據傳遞。為了運用一切的內存空間,8086設定了四個段存放器,專門用來保管段地址:CS(Code Segment):代碼段存放器;DS(Data Segment):數據段存放器;SS(Stack Segment):堆棧段存放器;ES(Extra Segment):附加段存放器。當一個順序要執行時,就要決議順序代碼、數據和堆棧各要用到內存的哪些地位,經過設定段存放器 CS,DS,SS 來指向這些起始地位。通常是將DS固定,而依據需求修正CS。所以,順序可以在可尋址空間小於64K的狀況下被寫成恣意大小。 所以,順序和其數據組合起來的大小,限制在DS 所指的64K內,這就是COM文件不得大於64K的緣由。8086以內存做為戰場,用存放器做為軍事基地,以減速任務。除了後面所提的存放器外,還有一些特殊功用的存放器:IP(Intruction Pointer):指令指針存放器,與CS配合運用,可跟蹤順序的執行進程;SP(Stack Pointer):堆棧指針,與SS配合運用,可指向目前的堆棧地位。BP(Base Pointer):基址指針存放器,可用作SS的一個絕對基址地位;SI(Source Index):源變址存放器可用來寄存絕對於DS段之源變址指針;DI(Destination Index):目的變址存放器,可用來寄存絕對於 ES 段之目的變址指針。還有一個標志存放器FR(Flag Register),有九個有意義的標志,將在下文用到時詳細闡明。

  內存是電腦運作中的關鍵局部,也是電腦在任務中貯存信息的中央。內存組織有許多可寄存數值的貯存地位,叫“地址”。8086地址總線有20位,所以CPU擁有達1M的尋址空間,這也是DOS的無效控制范圍,而8086能做的運算僅限於處置16位數據,即只要0到64K,所以,必需用分段尋址才干控制整個內存地址。完好的20位地址可分紅兩部份:1.段基址(Segment):16位二進制數前面加上四個二進制0,即一個16進制0,變成20位二進制數,可設定1M中任何一個64K段,通常記做16位二進制數;2.偏移量(Offset):直接運用16位二進制數,指向段基址中的任何一個地址。如:2222(段基址):3333(偏移量),其實踐的20位地址值為:25553。除了上述養分要充沛吸收外,你還要知道什麼是DOS、BIOS功用調用,復雜的說,功用調用相似於WIN95 API,相當於子順序。匯編寫順序曾經夠要命了,假如不必MS、IBM的子順序,這日子真是沒法過了(關於功用調用詳見《電腦喜好者》98年11期)。

  編寫匯編言語有兩種次要的辦法:1.運用MASM或TASM等編譯器;2.運用除錯順序DEBUG.COM。DEBUG其實並不能算是一個編譯器,它的次要用處在於除錯,即修正匯編順序中的錯誤。不過,也可以用來寫短的匯編順序,尤其對初學者而言,DEBUG 更是最佳的入門工具。由於DEBUG操作容易:只需鍵入DEBUG回車,A回車即可停止匯編,進程復雜,而運用編譯器時,必需用到文本編輯器、編譯器自身、LINK以及EXE2BIN等順序,其中每一個順序都必需用到一系列相當復雜的命令才干任務,而且用編譯器處置源順序,必需參加許多與指令語句有關的指示性語句,以供編譯器辨認,運用 DEBUG 可以防止一開端就碰到許多難以了解的順序行。DEBUG 除了可以匯編順序之外,還可用來反省和修正內存地位、載入貯存和執行順序、以及反省和修正存放器,換句話說,DEBUG是為了讓我們接觸硬件而設計的。(8086常用指令用法將在每個匯編順序中解說,限於篇幅,不能夠將一切指令列出)。

  DEBUG的的A命令可以匯編出復雜的COM文件,所以DEBUG編寫的順序一定要由地址 100h(COM文件要求)開端才合法。FOLLOW ME,SETP BY SETP(步步回車):

  輸出 A100 ; 從DS:100開端匯編
   2.輸出 MOV DL,1 ; 將數值 01h 裝入 DL 存放器
   3.輸出 MOV AH,2 ; 將數值 02h 裝入 DL 存放器
   4.輸出 INT 21 ; 調用DOS 21號中綴2號功用,用來逐一顯示裝入DL的字符
   5.輸出 INT 20 ; 調用DOS 20號中綴,終止順序,將控制權交回給 DEBUG
   6.請按 Enter 鍵
   7.如今已將匯編言語順序放入內存中了,輸出 G(運轉)
   8.呈現後果:輸入一個符號。
   ㄖ ←輸入後果其實不是它,因WORD97無法顯示原後果,故找一赝品將就著。
   Program terminated normally

  我們可以用U命令將十六進制的機器碼反匯編(Unassemble)成匯編指令。你將發現每一行左邊的匯編指令就是被匯編成相應的機器碼,而8086實踐上就是以機器碼來執行順序。
   1.輸出 U100,106
   1FED:0100 B201 MOV DL,01
   1FED:0102 B402 MOV AH,02
   1FED:0104 CD21 INT 21
   1FED:0106 CD20 INT 20
   DEBUG可以用R命令來檢查、改動存放器內容。CS:IP存放器,保管了將執行指令地址。
   1.輸出R
   AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
   DS=1FED ES=1FED SS=1FED CS=1FED IP=0100 NV UP EI PL NZ NA PO NC
   1FED:0100 B201 MOV DL,01

  當順序由DS:100開端執行,那麼終止順序時,DEBUG會自動將IP內容重新設定為100。當你要將此順序做成一個獨立的可執行文件,則可以用N命令對該順序命名。但一定要為COM文件,否則無法以DEBUG載入。
   輸出N SMILE.COM ;我們得通知DEBUG順序長度:順序從100開端到106,故占用7
   ;字節。我們應用BX寄存長度值高位局部,而以CX寄存低位局部。
   2.輸出RBX ;檢查 BX 存放器的內容,本順序只要7個字節,故本步可省略
   3.輸出 RCX  ;檢查 CX 存放器的內容
   4.輸出 7  ;順序的字節數
   5.輸出 W ;用W命令將該順序寫入(Write)磁盤中

  修行至此,我們便可以真正接觸8086匯編指令了。 當我們寫匯編言語順序的時分,通常不會直接將機器碼放入內存中,而是打入一串助記符號(Mnemonic Symbols),這些符號比十六進制機器碼更容易記住,此之謂匯編指令。助記符號,通知CPU應執行何種運算。 也就是說,助憶符號所構成的匯編言語是為人設計的,而機器言語是對PC設計的。

  如今,我們再來分析一個可以將一切ASCII碼顯示出來的順序。
   1. 輸出 DEBUG
   2. 輸出 A100
   3.輸出 MOV CX,0100 ;裝入循環次數
   MOV DL,00 ;裝入第一個ASCII碼,隨後每次循環裝入新碼
   MOV AH,02
   INT 21
   INC DL ;INC:遞增指令,每次將數據存放器 DL 內的數值加 1
   LOOP 0105 ;LOOP:循環指令,每執行一次LOOP,CX值減1,並跳
   ;到循環的起始地址105,直到CX為0,循環中止
   INT 20
   4.輸出 G即可顯示一切ASCII碼
 
   當我們想恣意顯示字符串,如:UNDERSTAND?,則可以運用DOS21H號中綴9H號功用。輸出下行順序,存盤並執行看看:
   1.輸出 A100
   MOV DX,109 ;DS:DX = 字符串的起始地址
   MOV AH,9 ;DOS的09h功用調用
   INT 21 ;字符串輸入
   INT 20
   DB 'UNDERSTAND?$';定義字符串

  在匯編言語中,有兩種不同的指令:1.正軌指令:如 MOV 等,是屬於CPU的指令,用來通知CPU在順序執行時應做些什麼,所以它會以運算碼(OP-code)的方式存入內存中;2.偽指令:如DB等,是屬於DEBUG等編譯器的指令,用來通知編譯器在編譯時應做些什麼。DB(Define Byte)指令用來通知DEBUG 將單引號內的一切ASCII 碼放入內存中。運用 9H 功用的字符串必需以$開頭。用D命令可用來檢查DB偽指令將那些內容放入內存。
   6.輸出 D100
   1975:0100 BA 09 01 B4 09 CD 21 CD-20 75 6E 64 65 72 73 74 ......!. underst
   1975:0110 61 6E 64 24 8B 46 F8 89-45 04 8B 46 34 00 64 19 and$.F..E..F4.d.
   1975:0120 89 45 02 33 C0 5E 5F C9-C3 00 C8 04 00 00 57 56 .E.3.^_.......WV
   1975:0130 6B F8 0E 81 C7 FE 53 8B-DF 8B C2 E8 32 FE 0B C0 k.....S.....2...
   1975:0140 74 05 33 C0 99 EB 17 8B-45 0C E8 D4 97 8B F0 89 t.3.....E.......
   1975:0150 56 FE 0B D0 74 EC 8B 45-08 03 C6 8B 56 FE 5E 5F V...t..E....V.^_
   1975:0160 C9 C3 C8 02 00 00 6B D8-0E 81 C3 FE 53 89 5E FE ......k.....S.^.
   1975:0170 8B C2 E8 FB FD 0B C0 75-09 8B 5E FE 8B 47 0C E8 .......u..^..G..

  如今,我們來分析另一個順序:由鍵盤輸出恣意字符串,然後顯示出來。db 20指示DEBUG保存20h個未用的內存空間供緩沖區運用。
   輸出A100
   MOV DX,0116 ;DS:DX = 緩沖區地址,由DB偽指令確定緩沖區地址
   MOV AH,0A ;0Ah 號功用調用
   INT 21 ;鍵盤輸出緩沖區
   MOV DL,0A ;由於功用Ah在每個字符串最後加一個歸位碼(0Dh由 Enter
   MOV AH,02 ;發生),使光標自動回到輸出行的最前端,為了使新輸入的
   INT 21 ;字符串不會蓋掉原來輸出的字符串,所以應用功用2h加一
   ;個換行碼(OAh),使得光標移到下一行的的最前端。
   MOV DX,0118 ;裝入字符串的起始地位
   MOV AH,09 ;9h功用遇到$符號才會中止輸入,故字符串最後必需加上
   INT 21 ;$,否則9h功用會持續將內存中的無用數據胡亂顯示出來
   INT 20
   DB 20 ;定義緩沖區
   送你一句話:學匯編切忌心浮氣燥。

  客套話就不講了。工欲善其事,必先利其器。與其說DEBUG 是編譯器,倒不如說它是“直譯器”,DEBUG的A命令只可將一行匯編指令轉成機器言語,且立即執行。真正編譯器(MASM)的運作是應用文本編輯器(EDIT等)將匯編指令建成一個獨立且附加名為.ASM的文本文件,稱源順序。它是MASM 順序的輸出局部。MASM將輸出的ASM文件,編譯成.OBJ文件,稱為目的順序。OBJ文件僅包括有關順序各部份要載入何處及如何與其他順序兼並的信息,無法直接載入內存執行。鏈結順序LINK則可將OBJ文件轉換成可載入內存執行(EXEcute)的EXE文件。還可以用EXE2BIN,將契合條件的EXE文件轉成COM文件(COM 文件不但占用的內存最少,而且運轉速度最快)。
   上面我們用MASM寫一個與用DEBUG寫的第一個順序功用一樣的順序。
   用EDIT編輯一個SMILE.ASM的源順序文件。
   源順序 DEBUG 順序
   prognam segment
   assume cs:prognam
   org 100h A100
   mov dl,1 mov dl,1
   mov ah,2 mov ah,2
   int 21h int 21
   int 20h int 20
   prognam ends
   end

  比擬一下:1.由於MASM會將一切的數值假定為十進制,而DEBUG則只運用十六進制,所以在源順序中,我們必需在有關數字後加上代表進制的字母,如H代表十六進制,D代表十進制。若是以字母掃尾的十六進制數字,還必需在字母前加個0,以表示它是數,如0AH。2.源順序添加五行敘說:prognam segment 與 prognam ends 是成對的,用來通知 MASM 及LINK,此順序將放在一個稱為PROGNAM(PROGram NAMe)的順序段內,其中段名(PROGNAM)可以任取,但其地位必需固定。assume cs:prognam 必需在順序的掃尾,用來通知編譯器此順序所在段的地位放在CS存放器中。end用來通知MASM,順序到此完畢, ORG 100H作用相當於DEBUG的A100,從偏移量100開端匯編。COM 文件的一切源順序都必需包括這五行,且必需依相反的次第及地位呈現,這點東西記下就行,千篇一概。接著,我們用MASM編譯SMILE.ASM。
   輸出 MASM SMILE ←不必打入附加名.ASM。
   Microsoft (R) Macro Assembler Version 5.10
   Copyright (C) Microsoft Corp 1981, 1988. All rights reserved.
   Object filename [SMILE.OBJ]: ←能否改動輸入OBJ文件名,如不改就ENTER
   Source listing [NUL.LST]: ← 能否需求列表文件(LST),不需求就ENTER
   Cross-reference [NUL.CRF]: ←能否需求對照文件(CRF),不需求則ENTER
   50162 + 403867 Bytes symbol space free
   0 Warning Errors ←正告錯誤,表示編譯器對某些語句不了解,通常是輸出錯誤。
   0 Severe Errors ←嚴重錯誤,會形成順序無法執行,通常是語法構造錯誤。

  假如沒有一個錯誤存在,即可生成OBJ文件。OBJ中包括的是編譯後的二進制後果,它還無法被 DOS載入內存中加以執行,必需加以鏈結(Linking)。以LINK將OBJ文件(SMILE.OBJ)鏈結成 EXE 文件(SMILE.EXE)時,。
   1.輸出 LINK SMILE ←不必附加名OBJ
   Microsoft (R) Overlay Linker Version 3.64
   Copyright (C) Microsoft Corp 1981, 1988. All rights reserved.
   Run File [SMILE.EXE]: ← 能否改動輸入EXE文件名,如不改就ENTER
   List File [NUL.MAP]: ← 能否需求列表文件(MAP),不需求則ENTER
   Libraries [.LIB]: ←能否需求庫文件,要就鍵入文件名,不要則ENTER
   LINK : warning L4021: no stack segment← 由於COM文件不運用堆棧段,所以錯誤信息
   ←"no stack segment"並不影響順序正常執行

  至此曾經生成EXE文件,我們還須運用EXE2BIN 將EXE文件(SMILE.EXE),轉換成COM文件(SMILE.COM)。輸出EXE2BIN SMILE發生 BIN 文件(SMILE.BIN)。其實 BIN 文件與 COM 文件是完全相反的,但由於DOS只認COM、EXE及BAT文件,所以BIN文件無法被正確執行,改名或直接輸出 EXE2BIN SMILE SMILE.COM即可。如今,磁盤上應該有 SMILE.COM 文件了,你只需在提示符號C:>下,直接輸出文件稱號 SMILE ,就可以執行這個順序了。

  你能否覺得用編譯器發生順序的辦法,比 DEBUG 費事多了!以小順序而言,確實是如此,但關於較大的順序,你就會發現其優點了。我們再將ASCII順序以編譯器方式再做一次,看看有無差別。首先,用EDIT.COM樹立 ASCII.ASM 文件。
   prognam segment ;定義段
   assume cs:prognam ;把下面定義段的段基址放入 CS
   mov cx,100h ; 裝入循環次數
   mov dl,0 ; 裝入第一個ASCII碼,隨後每次循環裝入新碼
   next: mov ah,2
   int 21h
   inc dl ;INC:遞增指令,每次將數據存放器 DL 內的數值加 1
   loop next ; 循環指令,執行一次,CX減1,直到CX為0,循環中止
   int 20h
   prognam ends ;段終止
   end ;匯編終止
   在匯編言語的源順序中,每一個順序行都包括三項元素:
    start: mov dl,1 ;裝入第一個ASCII碼,隨後每次循環裝入新碼
    標識符 表達式 注解

  在原始文件中加上注解可使順序更易了解,便於當前參考。每行注解以“;”與順序行別離。編譯器對注解不予理睬,注解的數據不會呈現在OBJ、EXE或COM文件中。由於我們在寫源順序時,並不知道每一順序行的地址,所以必需以符號稱號來代表絕對地址,稱為“標識符”。我們通常在適當行的適當地位上,鍵入標識符。標識符(label)最長可達31 個字節,因而我們在順序中,盡量以簡約的文字做為標識符。如今,你可以將此ASCII.ASM 文件編譯成 ASCII.COM 了。1.MASM ASCII,2.LINK ASCII,3.EXE2BIN ASCII ASCII.COM。

  留意:當你以編譯器匯編你設計的順序時,常會發作打字錯誤、標識符稱號拼錯、十六進制數少了h、邏輯錯誤等。匯編新手常給新人的忠告是:最好料到自己所寫的順序一定會有些錯誤(他人通知我的);假如第一次執行順序後,就失掉希冀的後果,你最好還是在反省一遍,由於它能夠是錯的。准繩上,只需大體的邏輯架構正確,查找順序中錯誤的進程,與寫順序自身相比甚至更有意思。寫大順序時,最好能分紅許多模塊,如此可使順序自身的目的較單純,易於撰寫與查錯,另外也可讓順序中不同部份之間的界線較清楚,節省編譯的時間。假如讀順序有讀不懂的中央最好用紙筆記下有關存放器、內存等外容,在紙上漸漸比劃,就恍然大悟了。   上面我們將寫一個能從鍵盤獲得一個十進制的數值,並將其轉換成十六進制數值而顯示於屏幕上的“大順序”。前言:要讓8086執行這樣的功用,我們必需先將此問題分解成一連串的步驟,稱為順序規劃。首先,以流程圖的方式,來確保整個順序在邏輯上沒有問題(不必說了吧!什麼言語都要有此步驟)。這種模塊化的規劃方式,稱之為“由上而下的順序規劃”。而在真正寫順序時,卻是從最小的單位模塊(子順序)開端,當每個模塊都完成之後,再兼並成大順序;這種大處著眼,小處著手的方式稱為“由下而上的順序設計”。

  我們的第一個模塊是BINIHEX,其次要用處是從8086的BX存放器中取出二進制數,並以十六進制方式顯示在屏幕上。留意:子順序如不能獨立運轉,實屬正常。
   binihex segment
   assume cs:binihex
   mov ch,4 ;記載轉換後的十六進制位數(四位)
   rotate: mov cl,4 ;應用CL當計數器,記載存放器數位挪動次數
   rol bx,cl ;循環存放器BX的內容,以便依序處置4個十六進制數
   mov al,bl ;把bx低八位bl內數據轉移至al
   and al,0fh ;把無用位清零
   add al,30h ;把AL內數據加30H,並存入al
   cmp al,3ah ;與3ah比擬
   jl printit ;小於3ah則轉移
   add al,7h ;把AL內數據加30H,並存入al
   printit:mov dl,al ;把ASCII碼裝入DL
   mov ah,2
   int 21h
   dec ch ;ch減一,減到零時,零標志置1
   jnz rotate ;JNZ:當零標志未置1,則跳到指定地址。即:不等,則轉移
   int 20h ;從子順序退回主順序
   binihex ends
   end

  應用循環左移指令ROL循環存放器BX(BX內容將由第二個子順序提供)的內容,以便依序處置4個十六進制數:1. 應用CL當計數器,記載存放器移位的次數。2.將BX的第一個十六進制值移到最左邊。應用 AND (邏輯“與”運算:對應位都為1時,其後果為1,其他狀況為零)把不要的部份清零,失掉後果:先將BL值存入AL中,再應用AND以0Fh(00001111)將AL的右邊四位清零。由於0到9的ASCII碼為30h到39h,而A到F之ASCII碼為41h到46h,連續了7h,所以失掉後果:若AL之內容小於3Ah,則AL值只加30h,否則AL再加7h。ADD指令會將兩個表達式相加,其後果存於右邊表達式內。標志存放器(Flag Register)是一個獨自的十六位存放器,有9個標志位,某些匯編指令(大部份是觸及比擬、算術或邏輯運算的指令)執行時,會將相關標志地位1或清0, 常碰到的標志位有零標志(ZF)、符號標志(SF)、溢出標志(OF)和進位標志(CF)。 標志位保管了某個指令執行後對它的影響,可用其他相關指令,查出標志的形態,依據形態發生舉措。CMP指令很像減法,是將兩個表達式的值相減,但存放器或內存的內容並未改動,只是絕對的標志位發作改動而已:若 AL 值小於 3Ah,則正負號標志位會置0,反之則置1。 JL指令可解釋為:小於就轉移到指定地位,大於、等於則向下執行。CMP和JG 、JL等條件轉移指令一同運用,可以構成順序的分支構造,是寫匯編順序常用技巧。

  第二個模塊DECIBIN 用來接納鍵盤打入的十進制數,並將它轉換成二進制數放於BX 存放器中,供模塊1 BINIHEX運用。
   decibin segment
   assume cs:decibin
   mov bx,0 ;BX清零
   newchar:mov ah,1 ;
   int 21h ;讀一個鍵盤輸出符號入al,並顯示
   sub al,30h ;al減去30H,後果存於al中,完成ASCII碼轉二進制碼
   jl exit ;小於零則轉移
   cmp al,9d
   jg exit ;左>右則轉移
   cbw ;8位al轉換成16位ax
   xchg ax,bx ;互換ax和bx內數據
   mov cx,10d ;十進制數10入cx
   mul cx ;表達式的值與ax內容相乘,並將後果存於ax
   xchg ax,bx
   add bx,ax
   jmp newchar ;無條件轉移
   exit: int 20 ;回主順序
   decibin ends
   end
   CBW 實踐後果是:若AL中的值為正,則AH填入00h;反之,則AH填入FFh。XCHG常用於需求暫時保存某個存放器中的內容時。
   當然,還得一個子順序(CRLF)使後顯示的十六進制數不會蓋掉先輸出的十進制數。
   crlf segment
   assume cs:crlf
   mov dl,0dh ;回車的ASCII碼0DH入DL
   mov ah,2
   int 21h
   mov dl,0ah ;換行的ASSII碼0AH入AH
   mov ah,2
   int 21h
   int 20 ;回主順序
   crlf ends
   end

  如今我們就可以將BINIHEX、DECIBIN及CRLF等模塊兼並成一個大順序了。首先,我們要將這三個模塊子順序略加改動。然後,再寫一段順序來調用每一個子順序。
   crlf proc near;
   mov dl,0dh
   mov ah,2
   int 21h
   mov dl,0ah
   mov ah,2
   int 21h
   ret
   crlf endp

  相似SEGMENT與ENDS的偽指令,PROC與ENDP也是成對呈現,用來辨認並定義一個順序。其實,PROC 真正的作用只是通知編譯器:所調用的順序是屬於遠程(NEAR)或近程(FAR)。 普通的順序是由 DEBUG 直接調用的,所以用 INT 20 前往,用 CALL 指令所調用的順序則改用前往指令RET,RET會把控制權轉移到棧頂所指的地址,而該地址是由調用此順序的 CALL指令所放入的。
   各模塊都搞定了,然後我們把子順序組合起來就半途而廢
   decihex segment ;主順序
   assume cs:decihex
   org 100h
   mov cx,4 ;循環次數入cx;由於子順序要用到cx,故子順序要將cx入棧
   repeat: call decibin;調用十進制轉二進制子順序
   call crlf ;調用添加回、換行符子順序
   call binihex ;調用二進制轉十六進制並顯示子順序
   call crlf
   loop repeat ;循環4次,可延續運算4次
   mov ah,4ch ; 調用DOS21號中綴4c號功用,加入順序,作用跟INT 20H
   int 21H ; 一樣,但適用面更廣,INT20H退不出時,試一下它
   decibin proc near push cx ;將cx壓入堆棧,;
   ┇ exit: pop cx ;將cx復原; retdecibin endp binihex proc near push cx
   ┇ pop cx retbinihex endp crlf proc near
   push cx
   ┇ pop cx retcrlf endpdecihex ends end

  CALL指令用來調用子順序,並將控制權轉移到子順序地址,同時將CALL的下行一指令地址定為前往地址,並壓入堆棧中。CALL 可分為遠程(NEAR)及近程(FAR)兩種:1.NEAR:IP的內容被壓入堆棧中,用於順序與順序在同一段中。2.FAR:CS 、IP存放器的內容順次壓入堆棧中,用於順序與順序在不同段中。PUSH、POP又是一對指令用於將存放器內容壓入、彈出,用來維護存放器數據,子順序調用中運用較多。堆棧指針有個“後進先出”准繩,像PUSH AX,PUSH BX…POP BX,POP AX這樣才干作到維護數據絲毫不差。

  匯編言語超稀釋教程到這要告一段落了,希望能奠定你獨立設計的根底。而更多更好的技巧則全依賴你平常的積聚了。祝你成功!
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved