沈陽電腦維修網,沈陽上門維修電腦服務
當前位置: 主頁 > 沈陽網站建設>※沈陽電腦維修※匯編語言超濃縮教程 >

※沈陽電腦維修※匯編語言超濃縮教程

時間:2011-6-9來源:www.tihyyw.tw 作者: 沈陽網站建設點擊:
沈陽電腦維修,上門維修電腦
“哎喲,哥們兒,還搗鼓匯編呢?那東西沒用,兄弟用VB"釣"一個API就夠你忙活個十天半月的,還不一定搞出來。”此君之言倒也不虛,那吾等還有無必要研他一究呢?(廢話,當然有啦!要不然你寫這篇文章干嘛。)別急,別急,讓我把這個中原委慢慢道來:一、所有電腦語言寫出的程序運行時在內存中都以機器碼方式存儲,機器碼可以被比較準確的翻譯成匯編語言,這是因為匯編語言兼容性最好,故幾乎所有跟蹤、調試工具(包括WIN95/98下)都是以匯編示人的,如果閣下對CRACK頗感興趣……;二、匯編直接與硬件打交道,如果你想搞通程序在執行時在電腦中的來龍去脈,也就是搞清電腦每個組成部分究竟在干什么、究竟怎么干?一個真正的硬件發燒友,不懂這些可不行。三、如今玩DOS的多是“高手”,如能像吾一樣混入(我不是高手)“高手”內部,不僅可以從“高手”朋友那兒套些黑客級“機密”,還可以自詡“高手”盡情享受強烈的虛榮感--#$%&“醒醒!” 對初學者而言,匯編的許多命令太復雜,往往學習很長時間也寫不出一個漂漂亮亮的程序,以致妨礙了我們學習匯編的興趣,不少人就此放棄。所以我個人看法學匯編,不一定要寫程序,寫程序確實不是匯編的強項,大家不妨玩玩DEBUG,有時CRACK出一個小軟件比完成一個程序更有成就感(就像學電腦先玩游戲一樣)。某些高深的指令事實上只對有經驗的匯編程序員有用,對我們而言,太過高深了。為了使學習匯編語言有個好的開始,你必須要先排除那些華麗復雜的命令,將注意力集中在最重要的幾個指令上(CMPLOOPMOVJNZ……)。但是想在啰里吧嗦的教科書中完成上述目標,談何容易,所以本人整理了這篇超濃縮(用WINZIP、WINRAR…依次壓迫,嘿嘿!)教程。大言不慚的說,看通本文,你完全可以“不經意”間在前輩或是后生賣弄一下DEBUG,很有成就感的,試試看!那么――這個接下來呢?――Herewego!(閱讀時看不懂不要緊,下文必有分解)因為匯編是通過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(CodeSegment):代碼段寄存器;DS(DataSegment):數據段寄存器;SS(StackSegment):堆棧段寄存器;ES(ExtraSegment):附加段寄存器。當一個程序要執行時,就要決定程序代碼、數據和堆棧各要用到內存的哪些位置,通過設定段寄存器CS,DS,SS來指向這些起始位置。通常是將DS固定,而根據需要修改CS。所以,程序可以在可尋址空間小于64K的情況下被寫成任意大小。所以,程序和其數據組合起來的大小,限制在DS所指的64K內,這就是COM文件不得大于64K的原因。8086以內存做為戰場,用寄存器做為軍事基地,以加速工作。除了前面所提的寄存器外,還有一些特殊功能的寄存器:IP(IntructionPointer):指令指針寄存器,與CS配合使用,可跟蹤程序的執行過程;SP(StackPointer):堆棧指針,與SS配合使用,可指向目前的堆棧位置。BP(BasePointer):基址指針寄存器,可用作SS的一個相對基址位置;SI(SourceIndex):源變址寄存器可用來存放相對于DS段之源變址指針;DI(DestinationIndex):目的變址寄存器,可用來存放相對于ES段之目的變址指針。還有一個標志寄存器FR(FlagRegister),有九個有意義的標志,將在下文用到時詳細說明。內存是電腦運作中的關鍵部分,也是電腦在工作中儲存信息的地方。內存組織有許多可存放數值的儲存位置,叫“地址”。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功能調用,簡單的說,功能調用類似于WIN95API,相當于子程序。匯編寫程序已經夠要命了,如果不用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文件要求)開始才合法。FOLLOWME,SETPBYSETP(步步回車):輸入A100;從DS:100開始匯編 2.輸入MOVDL,1;將數值01h裝入DL寄存器 3.輸入MOVAH,2;將數值02h裝入DL寄存器 4.輸入INT21;調用DOS21號中斷2號功能,用來逐個顯示裝入DL的字符 5.輸入INT20;調用DOS20號中斷,終止程序,將控制權交回給DEBUG 6.請按Enter鍵 7.現在已將匯編語言程序放入內存中了,輸入G(運行) 8.出現結果:輸出一個符號。ㄖ←輸出結果其實不是它,因WORD97無法顯示原結果,故找一贗品將就著。 Programterminatednormally 我們可以用U命令將十六進制的機器碼反匯編(Unassemble)成匯編指令。你將發現每一行右邊的匯編指令就是被匯編成相應的機器碼,而8086實際上就是以機器碼來執行程序。 1.輸入U100,106 1FED:0100B201MOVDL,01 1FED:0102B402MOVAH,02 1FED:0104CD21INT21 1FED:0106CD20INT20 DEBUG可以用R命令來查看、改變寄存器內容。CS:IP寄存器,保存了將執行指令地址。 1.輸入R AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000 DS=1FEDES=1FEDSS=1FEDCS=1FEDIP=0100NVUPEIPLNZNAPONC 1FED:0100B201MOVDL,01 當程序由DS:100開始執行,那么終止程序時,DEBUG會自動將IP內容重新設定為100。當你要將此程序做成一個獨立的可執行文件,則可以用N命令對該程序命名。但一定要為COM文件,否則無法以DEBUG載入。輸入NSMILE.COM;我們得告訴DEBUG程序長度:程序從100開始到106,故占用7 ;字節。我們利用BX存放長度值高位部分,而以CX存放低位部分。 2.輸入RBX;查看BX寄存器的內容,本程序只有7個字節,故本步可省略 3.輸入RCX ;查看CX寄存器的內容 4.輸入7 ;程序的字節數 5.輸入W;用W命令將該程序寫入(Write)磁盤中修行至此,我們便可以真正接觸8086匯編指令了。當我們寫匯編語言程序的時候,通常不會直接將機器碼放入內存中,而是打入一串助記符號(MnemonicSymbols),這些符號比十六進制機器碼更容易記住,此之謂匯編指令。助記符號,告訴CPU應執行何種運算。也就是說,助憶符號所構成的匯編語言是為人設計的,而機器語言是對PC設計的。現在,我們再來剖析一個可以將所有ASCII碼顯示出來的程序。 1.輸入DEBUG 2.輸入A100 3.輸入MOVCX,0100;裝入循環次數 MOVDL,00;裝入第一個ASCII碼,隨后每次循環裝入新碼 MOVAH,02 INT21 INCDL;INC:遞增指令,每次將數據寄存器DL內的數值加1 LOOP0105;LOOP:循環指令,每執行一次LOOP,CX值減1,并跳;到循環的起始地址105,直到CX為0,循環停止 INT20 4.輸入G即可顯示所有ASCII碼當我們想任意顯示字符串,如:UNDERSTAND?,則可以使用DOS21H號中斷9H號功能。輸入下行程序,存盤并執行看看: 1.輸入A100 MOVDX,109;DS:DX=字符串的起始地址 MOVAH,9;DOS的09h功能調用 INT21;字符串輸出 INT20 DBUNDERSTAND?$;定義字符串在匯編語言中,有兩種不同的指令:1.正規指令:如MOV等,是屬于CPU的指令,用來告訴CPU在程序執行時應做些什么,所以它會以運算碼(OP-code)的方式存入內存中;2.偽指令:如DB等,是屬于DEBUG等編譯器的指令,用來告訴編譯器在編譯時應做些什么。DB(DefineByte)指令用來告訴DEBUG將單引號內的所有ASCII碼放入內存中。使用9H功能的字符串必須以$結尾。用D命令可用來查看DB偽指令將那些內容放入內存。 6.輸入D100 1975:0100BA0901B409CD21CD-20756E6465727374......!.underst 1975:0110616E64248B46F889-45048B4634006419and$.F..E..F4.d. 1975:012089450233C05E5FC9-C300C80400005756.E.3.^_.......WV 1975:01306BF80E81C7FE538B-DF8BC2E832FE0BC0k.....S.....2... 1975:0140740533C099EB178B-450CE8D4978BF089t.3.....E....... 1975:015056FE0BD074EC8B45-0803C68B56FE5E5FV...t..E....V.^_ 1975:0160C9C3C80200006BD8-0E81C3FE53895EFE......k.....S.^. 1975:01708BC2E8FBFD0BC075-098B5EFE8B470CE8.......u..^..G.. 現在,我們來剖析另一個程序:由鍵盤輸入任意字符串,然后顯示出來。db20指示DEBUG保留20h個未用的內存空間供緩沖區使用。輸入A100 MOVDX,0116;DS:DX=緩沖區地址,由DB偽指令確定緩沖區地址 MOVAH,0A;0Ah號功能調用 INT21;鍵盤輸入緩沖區 MOVDL,0A;由于功能Ah在每個字符串最后加一個歸位碼(0Dh由Enter MOVAH,02;產生),使光標自動回到輸入行的最前端,為了使新輸出的 INT21;字符串不會蓋掉原來輸入的字符串,所以利用功能2h加一;個換行碼(OAh),使得光標移到下一行的的最前端。 MOVDX,0118;裝入字符串的起始位置 MOVAH,09;9h功能遇到$符號才會停止輸出,故字符串最后必須加上 INT21;$,否則9h功能會繼續將內存中的無用數據胡亂顯示出來 INT20 DB20;定義緩沖區送你一句話:學匯編切忌心浮氣燥。客套話就不講了。工欲善其事,必先利其器。與其說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程序 prognamsegment assumecs:prognam org100hA100 movdl,1movdl,1 movah,2movah,2 int21hint21 int20hint20 prognamends end 比較一下:1.因為MASM會將所有的數值假設為十進制,而DEBUG則只使用十六進制,所以在源程序中,我們必須在有關數字后加上代表進制的字母,如H代表十六進制,D代表十進制。若是以字母開頭的十六進制數字,還必須在字母前加個0,以表示它是數,如0AH。2.源程序增加五行敘述:prognamsegment與prognamends是成對的,用來告訴MASM及LINK,此程序將放在一個稱為PROGNAM(PROGramNAMe)的程序段內,其中段名(PROGNAM)可以任取,但其位置必須固定。assumecs:prognam必須在程序的開頭,用來告訴編譯器此程序所在段的位置放在CS寄存器中。end用來告訴MASM,程序到此結束,ORG100H作用相當于DEBUG的A100,從偏移量100開始匯編。COM文件的所有源程序都必須包含這五行,且必須依相同的次序及位置出現,這點東西記下就行,千篇一律。接著,我們用MASM編譯SMILE.ASM。輸入MASMSMILE←不用打入附加名.ASM。 Microsoft(R)MacroAssemblerVersion5.10 Copyright(C)MicrosoftCorp1981,1988.Allrightsreserved. Objectfilename[SMILE.OBJ]:←是否改動輸出OBJ文件名,如不改就ENTER Sourcelisting[NUL.LST]:←是否需要列表文件(LST),不需要就ENTER Cross-reference[NUL.CRF]:←是否需要對照文件(CRF),不需要則ENTER 50162+403867Bytessymbolspacefree 0WarningErrors←警告錯誤,表示編譯器對某些語句不理解,通常是輸入錯誤。 0SevereErrors←嚴重錯誤,會造成程序無法執行,通常是語法結構錯誤。如果沒有一個錯誤存在,即可生成OBJ文件。OBJ中包含的是編譯后的二進制結果,它還無法被DOS載入內存中加以執行,必須加以鏈結(Linking)。以LINK將OBJ文件(SMILE.OBJ)鏈結成EXE文件(SMILE.EXE)時,。 1.輸入LINKSMILE←不用附加名OBJ Microsoft(R)OverlayLinkerVersion3.64 Copyright(C)MicrosoftCorp1981,1988.Allrightsreserved. RunFile[SMILE.EXE]:←是否改動輸出EXE文件名,如不改就ENTER ListFile[NUL.MAP]:←是否需要列表文件(MAP),不需要則ENTER Libraries[.LIB]:←是否需要庫文件,要就鍵入文件名,不要則ENTER LINK:warningL4021:nostacksegment←由于COM文件不使用堆棧段,所以錯誤信息 ←"nostacksegment"并不影響程序正常執行至此已經生成EXE文件,我們還須使用EXE2BIN將EXE文件(SMILE.EXE),轉換成COM文件(SMILE.COM)。輸入EXE2BINSMILE產生BIN文件(SMILE.BIN)。其實BIN文件與COM文件是完全相同的,但由于DOS只認COM、EXE及BAT文件,所以BIN文件無法被正確執行,改名或直接輸入EXE2BINSMILESMILE.COM即可。現在,磁盤上應該有SMILE.COM文件了,你只要在提示符號C:>下,直接輸入文件名稱SMILE,就可以執行這個程序了。你是否覺得用編譯器產生程序的方法,比DEBUG麻煩多了!以小程序而言,的確是如此,但對于較大的程序,你就會發現其優點了。我們再將ASCII程序以編譯器方式再做一次,看看有無差異。首先,用EDIT.COM建立ASCII.ASM文件。 prognamsegment定義段 assumecs:prognam把上面定義段的段基址放入CS movcx,100h裝入循環次數 movdl,0裝入第一個ASCII碼,隨后每次循環裝入新碼 next:movah,2 int21h incdlINC:遞增指令,每次將數據寄存器DL內的數值加1 loopnext循環指令,執行一次,CX減1,直到CX為0,循環停止 int20h prognamends段終止 end匯編終止在匯編語言的源程序中,每一個程序行都包含三項元素: start:movdl,1;裝入第一個ASCII碼,隨后每次循環裝入新碼 標識符表達式注解在原始文件中加上注解可使程序更易理解,便于以后參考。每行注解以“;”與程序行分離。編譯器對注解不予理會,注解的數據不會出現在OBJ、EXE或COM文件中。由于我們在寫源程序時,并不知道每一程序行的地址,所以必須以符號名稱來代表相對地址,稱為“標識符”。我們通常在適當行的適當位置上,鍵入標識符。標識符(label)最長可達31個字節,因此我們在程序中,盡量以簡潔的文字做為標識符。現在,你可以將此ASCII.ASM文件編譯成ASCII.COM了。1.MASMASCII,2.LINKASCII,3.EXE2BINASCIIASCII.COM。注意:當你以編譯器匯編你設計的程序時,常會發生打字錯誤、標識符名稱拼錯、十六進制數少了h、邏輯錯誤等。匯編老手常給新人的忠告是:最好料到自己所寫的程序一定會有些錯誤(別人告訴我的);如果第一次執行程序后,就得到期望的結果,你最好還是在檢查一遍,因為它可能是錯的。原則上,只要大體的邏輯架構正確,查找程序中錯誤的過程,與寫程序本身相比甚至更有意思。寫大程序時,最好能分成許多模塊,如此可使程序本身的目的較單純,易于撰寫與查錯,另外也可讓程序中不同部份之間的界限較清楚,節省編譯的時間。如果讀程序有讀不懂的地方最好用紙筆記下有關寄存器、內存等內容,在紙上慢慢比劃,就豁然開朗了。下面我們將寫一個能從鍵盤取得一個十進制的數值,并將其轉換成十六進制數值而顯示于屏幕上的“大程序”。前言:要讓8086執行這樣的功能,我們必須先將此問題分解成一連串的步驟,稱為程序規劃。首先,以流程圖的方式,來確保整個程序在邏輯上沒有問題(不用說了吧!什么語言都要有此步驟)。這種模塊化的規劃方式,稱之為“由上而下的程序規劃”。而在真正寫程序時,卻是從最小的單位模塊(子程序)開始,當每個模塊都完成之后,再合并成大程序;這種大處著眼,小處著手的方式稱為“由下而上的程序設計”。我們的第一個模塊是BINIHEX,其主要用途是從8086的BX寄存器中取出二進制數,并以十六進制方式顯示在屏幕上。注意:子程序如不能獨立運行,實屬正常。 binihexsegment assumecs:binihex movch,4記錄轉換后的十六進制位數(四位) rotate:movcl,4利用CL當計數器,記錄寄存器數位移動次數 rolbx,cl循環寄存器BX的內容,以便依序處理4個十六進制數 moval,bl把bx低八位bl內數據轉移至al andal,0fh把無用位清零 addal,30h把AL內數據加30H,并存入al cmpal,3ah與3ah比較 jlprintit小于3ah則轉移 addal,7h把AL內數據加30H,并存入al printit:movdl,al把ASCII碼裝入DL movah,2 int21h decchch減一,減到零時,零標志置1 jnzrotateJNZ:當零標志未置1,則跳到指定地址。即:不等,則轉移 int20h從子程序退回主程序 binihexends 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指令會將兩個表達式相加,其結果存于左邊表達式內。標志寄存器(FlagRegister)是一個單獨的十六位寄存器,有9個標志位,某些匯編指令(大部份是涉及比較、算術或邏輯運算的指令)執行時,會將相關標志位置1或清0,常碰到的標志位有零標志(ZF)、符號標志(SF)、溢出標志(OF)和進位標志(CF)。標志位保存了某個指令執行后對它的影響,可用其他相關指令,查出標志的狀態,根據狀態產生動作。CMP指令很像減法,是將兩個表達式的值相減,但寄存器或內存的內容并未改變,只是相對的標志位發生改變而已:若AL值小于3Ah,則正負號標志位會置0,反之則置1。JL指令可解釋為:小于就轉移到指定位置,大于、等于則向下執行。CMP和JG、JL等條件轉移指令一起使用,可以形成程序的分支結構,是寫匯編程序常用技巧。第二個模塊DECIBIN用來接收鍵盤打入的十進制數,并將它轉換成二進制數放于BX寄存器中,供模塊1BINIHEX使用。 decibinsegment assumecs:decibin movbx,0BX清零 newchar:movah,1 int21h讀一個鍵盤輸入符號入al,并顯示 subal,30hal減去30H,結果存于al中,完成ASCII碼轉二進制碼 jlexit小于零則轉移 cmpal,9d jgexit左>右則轉移 cbw8位al轉換成16位ax xchgax,bx互換ax和bx內數據 movcx,10d十進制數10入cx mulcx表達式的值與ax內容相乘,并將結果存于ax xchgax,bx addbx,ax jmpnewchar無條件轉移 exit:int20回主程序 decibinends end CBW實際結果是:若AL中的值為正,則AH填入00h;反之,則AH填入FFh。XCHG常用于需要暫時保留某個寄存器中的內容時。當然,還得一個子程序(CRLF)使后顯示的十六進制數不會蓋掉先輸入的十進制數。 crlfsegment assumecs:crlf movdl,0dh回車的ASCII碼0DH入DL movah,2 int21h movdl,0ah換行的ASSII碼0AH入AH movah,2 int21h int20回主程序 crlfends end 現在我們就可以將BINIHEX、DECIBIN及CRLF等模塊合并成一個大程序了。首先,我們要將這三個模塊子程序略加改動。然后,再寫一段程序來調用每一個子程序。 crlfprocnear; movdl,0dh movah,2 int21h movdl,0ah movah,2 int21h ret crlfendp 類似SEGMENT與ENDS的偽指令,PROC與ENDP也是成對出現,用來識別并定義一個程序。其實,PROC真正的作用只是告訴編譯器:所調用的程序是屬于近程(NEAR)或遠程(FAR)。一般的程序是由DEBUG直接調用的,所以用INT20返回,用CALL指令所調用的程序則改用返回指令RET,RET會把控制權轉移到棧頂所指的地址,而該地址是由調用此程序的CALL指令所放入的。各模塊都搞定了,然后我們把子程序組合起來就大功告成 decihexsegment主程序 assumecs:decihex org100h movcx,4循環次數入cx;由于子程序要用到cx,故子程序要將cx入棧 repeat:calldecibin;調用十進制轉二進制子程序 callcrlf調用添加回、換行符子程序 callbinihex調用二進制轉十六進制并顯示子程序 callcrlf looprepeat循環4次,可連續運算4次 movah,4ch調用DOS21號中斷4c號功能,退出程序,作用跟INT20H int21H一樣,但適用面更廣,INT20H退不出時,試一下它 decibinprocnearpushcx將cx壓入堆棧,; ┇exit:popcx將cx還原;retdecibinendpbinihexprocnearpushcx ┇popcxretbinihexendpcrlfprocnear pushcx ┇popcxretcrlfendpdecihexendsend CALL指令用來調用子程序,并將控制權轉移到子程序地址,同時將CALL的下行一指令地址定為返回地址,并壓入堆棧中。CALL可分為近程(NEAR)及遠程(FAR)兩種:1.NEAR:IP的內容被壓入堆棧中,用于程序與程序在同一段中。2.FAR:CS、IP寄存器的內容依次壓入堆棧中,用于程序與程序在不同段中。PUSH、POP又是一對指令用于將寄存器內容壓入、彈出,用來保護寄存器數據,子程序調用中運用較多。堆棧指針有個“后進先出”原則,像PUSHAX,PUSHBX…POPBX,POPAX這樣才能作到保護數據絲毫不差。
上一篇:網站設計和網站建設要注意的幾點
下一篇:編程高手 ASP.NET 狀態管理
查看[※沈陽電腦維修※匯編語言超濃縮教程]所有評論
發表評論
請自覺遵守互聯網相關的政策法規,嚴禁發布色情、暴力、反動的言論。
用戶名: 驗證碼:
關于我們 服務價格 聯系我們 企業網站優化 沈陽網站建設 沈陽維修電腦
30选5开奖号码