




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
-.z.匯編語言入門教程2007-04-2922:04對初學(xué)者而言,匯編的許多命令太復(fù)雜,往往學(xué)習(xí)很長時(shí)間也寫不出一個(gè)漂漂亮亮的程序,以致阻礙了我們學(xué)習(xí)匯編的興趣,不少人就此放棄。所以我個(gè)人看法學(xué)匯編,不一定要寫程序,寫程序確實(shí)不是匯編的強(qiáng)項(xiàng),大家不妨玩玩DEBUG,有時(shí)CRACK出一個(gè)小軟件比完成一個(gè)程序更有成就感〔就像學(xué)電腦先玩游戲一樣〕。*些高深的指令事實(shí)上只對有經(jīng)歷的匯編程序員有用,對我們而言,太過高深了。為了使學(xué)習(xí)匯編語言有個(gè)好的開場,你必須要先排除那些華美復(fù)雜的命令,將注意力集中在最重要的幾個(gè)指令上〔CMPLOOPMOVJNZ……〕。但是想在啰里吧嗦的教科書中完成上述目標(biāo),談何容易,所以本人整理了這篇超濃縮〔用WINZIP、WINRAR…依次壓迫,嘿嘿!〕教程。大言不慚的說,看通本文,你完全可以"不經(jīng)意〞間在前輩或是后生賣弄一下DEBUG,很有成就感的,試試看!則――這個(gè)接下來呢?――Herewego!〔閱讀時(shí)看不懂不要緊,下文必有分解〕因?yàn)閰R編是通過CPU和內(nèi)存跟硬件對話的,所以我們不得不先了解一下CPU和內(nèi)存:〔關(guān)于數(shù)的進(jìn)制問題在此不提〕CPU是可以執(zhí)行電腦所有算術(shù)╱邏輯運(yùn)算與根本I/O控制功能的一塊芯片。一種匯編語言只能用于特定的CPU。也就是說,不同的CPU其匯編語言的指令語法亦不一樣。個(gè)人電腦由1981年推出至今,其CPU開展過程為:8086→80286→80386→80486→PENTIUM→……,還有AMD、CYRI*等旁支。后面兼容前面CPU的功能,只不過多了些指令〔如多能奔騰的MM*指令集〕、增大了存放器〔如386的32位EA*〕、增多了存放器〔如486的FS〕。為確保匯編程序可以適用于各種機(jī)型,所以推薦使用8086匯編語言,其兼容性最正確。本文所提均為8086匯編語言。存放器〔Register〕是CPU內(nèi)部的元件,所以在存放器之間的數(shù)據(jù)傳送非常快。用途:1.可將存放器內(nèi)的數(shù)據(jù)執(zhí)行算術(shù)及邏輯運(yùn)算。2.存于存放器內(nèi)的地址可用來指向內(nèi)存的*個(gè)位置,即尋址。3.可以用來讀寫數(shù)據(jù)到電腦的周邊設(shè)備。8086有8個(gè)8位數(shù)據(jù)存放器,這些8位存放器可分別組成16位存放器:AH&AL=AX:累加存放器,常用于運(yùn)算;BH&BL=BX:基址存放器,常用于地址索引;CH&CL=CX:計(jì)數(shù)存放器,常用于計(jì)數(shù);DH&DL=DX:數(shù)據(jù)存放器,常用于數(shù)據(jù)傳遞。為了運(yùn)用所有的內(nèi)存空間,8086設(shè)定了四個(gè)段存放器,專門用來保存段地址:CS〔CodeSegment〕:代碼段存放器;DS〔DataSegment〕:數(shù)據(jù)段存放器;SS〔StackSegment〕:堆棧段存放器;ES〔E*traSegment〕:附加段存放器。當(dāng)一個(gè)程序要執(zhí)行時(shí),就要決定程序代碼、數(shù)據(jù)和堆棧各要用到內(nèi)存的哪些位置,通過設(shè)定段存放器CS,DS,SS來指向這些起始位置。通常是將DS固定,而根據(jù)需要修改CS。所以,程序可以在可尋址空間小于64K的情況下被寫成任意大小。所以,程序和其數(shù)據(jù)組合起來的大小,限制在DS所指的64K內(nèi),這就是文件不得大于64K的原因。8086以內(nèi)存做為戰(zhàn)場,用存放器做為軍事基地,以加速工作。除了前面所提的存放器外,還有一些特殊功能的存放器:IP〔IntructionPointer〕:指令指針存放器,與CS配合使用,可跟蹤程序的執(zhí)行過程;SP〔StackPointer〕:堆棧指針,與SS配合使用,可指向目前的堆棧位置。BP〔BasePointer〕:基址指針存放器,可用作SS的一個(gè)相對基址位置;SI〔SourceInde*〕:源變址存放器可用來存放相對于DS段之源變址指針;DI〔DestinationInde*〕:目的變址存放器,可用來存放相對于ES段之目的變址指針。還有一個(gè)標(biāo)志存放器FR〔FlagRegister〕,有九個(gè)有意義的標(biāo)志,將在下文用到時(shí)詳細(xì)說明。內(nèi)存是電腦運(yùn)作中的關(guān)鍵局部,也是電腦在工作中儲存信息的地方。內(nèi)存組織有許多可存放數(shù)值的儲存位置,叫"地址〞。8086地址總線有20位,所以CPU擁有達(dá)1M的尋址空間,這也是DOS的有效控制范圍,而8086能做的運(yùn)算僅限于處理16位數(shù)據(jù),即只有0到64K,所以,必須用分段尋址才能控制整個(gè)內(nèi)存地址。完整的20位地址可分成兩部份:1.段基址(Segment):16位二進(jìn)制數(shù)后面加上四個(gè)二進(jìn)制0,即一個(gè)16進(jìn)制0,變成20位二進(jìn)制數(shù),可設(shè)定1M中任何一個(gè)64K段,通常記做16位二進(jìn)制數(shù);2.偏移量(Offset):直接使用16位二進(jìn)制數(shù),指向段基址中的任何一個(gè)地址。如:2222〔段基址〕:3333〔偏移量〕,其實(shí)際的20位地址值為:25553。除了上述營養(yǎng)要充分吸收外,你還要知道什么是DOS、BIOS功能調(diào)用,簡單的說,功能調(diào)用類似于WIN95API,相當(dāng)于子程序。匯編寫程序已經(jīng)夠要命了,如果不用MS、IBM的子程序,這日子真是沒法過了〔關(guān)于功能調(diào)用詳見"電腦愛好者"98年11期〕。編寫匯編語言有兩種主要的方法:1.使用MASM或TASM等編譯器;2.使用除錯(cuò)程序DEBUG.。DEBUG其實(shí)并不能算是一個(gè)編譯器,它的主要用途在于除錯(cuò),即修正匯編程序中的錯(cuò)誤。不過,也可以用來寫短的匯編程序,尤其對初學(xué)者而言,DEBUG更是最正確的入門工具。因?yàn)镈EBUG操作容易:只要鍵入DEBUG回車,A回車即可進(jìn)展匯編,過程簡單,而使用編譯器時(shí),必須用到文本編輯器、編譯器本身、LINK以及E*E2BIN等程序,其中每一個(gè)程序都必須用到一系列相當(dāng)復(fù)雜的命令才能工作,而且用編譯器處理源程序,必須參加許多與指令語句無關(guān)的指示性語句,以供編譯器識別,使用DEBUG可以防止一開場就碰到許多難以理解的程序行。DEBUG除了能夠匯編程序之外,還可用來檢查和修改內(nèi)存位置、載入儲存和執(zhí)行程序、以及檢查和修改存放器,換句話說,DEBUG是為了讓我們接觸硬件而設(shè)計(jì)的?!?086常用指令用法將在每個(gè)匯編程序中講解,限于篇幅,不可能將所有指令列出〕。DEBUG的的A命令可以匯編出簡單的文件,所以DEBUG編寫的程序一定要由地址100h〔文件要求〕開場才合法。FOLLOWME,SETPBYSETP〔步步回車〕:輸入A100;從DS:100開場匯編2.輸入MOVDL,1;將數(shù)值01h裝入DL存放器3.輸入MOVAH,2;將數(shù)值02h裝入DL存放器4.輸入INT21;調(diào)用DOS21號中斷2號功能,用來逐個(gè)顯示裝入DL的字符5.輸入INT20;調(diào)用DOS20號中斷,終止程序,將控制權(quán)交回給DEBUG6.請按Enter鍵7.現(xiàn)在已將匯編語言程序放入內(nèi)存中了,輸入G(運(yùn)行)8.出現(xiàn)結(jié)果:輸出一個(gè)符號。ㄖ←輸出結(jié)果其實(shí)不是它,因WORD97無法顯示原結(jié)果,故找一贗品將就著。Programterminatednormally我們可以用U命令將十六進(jìn)制的機(jī)器碼反匯編〔Unassemble〕成匯編指令。你將發(fā)現(xiàn)每一行右邊的匯編指令就是被匯編成相應(yīng)的機(jī)器碼,而8086實(shí)際上就是以機(jī)器碼來執(zhí)行程序。1.輸入U(xiǎn)100,1061FED:0100B201MOVDL,011FED:0102B402MOVAH,021FED:0104CD21INT211FED:0106CD20INT20DEBUG可以用R命令來查看、改變存放器內(nèi)容。CS:IP存放器,保存了將執(zhí)行指令地址。1.輸入RA*=0000B*=0000C*=0000D*=0000SP=FFEEBP=0000SI=0000DI=0000DS=1FEDES=1FEDSS=1FEDCS=1FEDIP=0100NVUPEIPLNZNAPONC1FED:0100B201MOVDL,01當(dāng)程序由DS:100開場執(zhí)行,則終止程序時(shí),DEBUG會自動將IP內(nèi)容重新設(shè)定為100。當(dāng)你要將此程序做成一個(gè)獨(dú)立的可執(zhí)行文件,則可以用N命令對該程序命名。但一定要為文件,否則無法以DEBUG載入。輸入NSMILE.;我們得告訴DEBUG程序長度:程序從100開場到106,故占用7字節(jié)。我們利用B*存放長度值高位局部,而以C*存放低位局部。2.輸入RB*;查看B*存放器的內(nèi)容,本程序只有7個(gè)字節(jié),故本步可省略3.輸入RC*;查看C*存放器的內(nèi)容4.輸入7;程序的字節(jié)數(shù)5.輸入W;用W命令將該程序?qū)懭搿瞁rite〕磁盤中修行至此,我們便可以真正接觸8086匯編指令了。當(dāng)我們寫匯編語言程序的時(shí)候,通常不會直接將機(jī)器碼放入內(nèi)存中,而是打入一串助記符號〔MnemonicSymbols〕,這些符號比十六進(jìn)制機(jī)器碼更容易記住,此之謂匯編指令。助記符號,告訴CPU應(yīng)執(zhí)行何種運(yùn)算。也就是說,助憶符號所構(gòu)成的匯編語言是為人設(shè)計(jì)的,而機(jī)器語言是對PC設(shè)計(jì)的?,F(xiàn)在,我們再來剖析一個(gè)可以將所有ASCII碼顯示出來的程序。1.輸入DEBUG2.輸入A1003.輸入MOVC*,0100;裝入循環(huán)次數(shù)MOVDL,00;裝入第一個(gè)ASCII碼,隨后每次循環(huán)裝入新碼MOVAH,02INT21INCDL;INC:遞增指令,每次將數(shù)據(jù)存放器DL內(nèi)的數(shù)值加1LOOP0105;LOOP:循環(huán)指令,每執(zhí)行一次LOOP,C*值減1,并跳到循環(huán)的起始地址105,直到C*為0,循環(huán)停頓INT204.輸入G即可顯示所有ASCII碼當(dāng)我們想任意顯示字符串,如:UNDERSTAND?,則可以使用DOS21H號中斷9H號功能。輸入下行程序,存盤并執(zhí)行看看:1.輸入A100MOVD*,109;DS:D*=字符串的起始地址MOVAH,9;DOS的09h功能調(diào)用INT21;字符串輸出INT20DB'UNDERSTAND?$';定義字符串在匯編語言中,有兩種不同的指令:1.正規(guī)指令:如MOV等,是屬于CPU的指令,用來告訴CPU在程序執(zhí)行時(shí)應(yīng)做些什么,所以它會以運(yùn)算碼〔OP-code〕的方式存入內(nèi)存中;2.偽指令:如DB等,是屬于DEBUG等編譯器的指令,用來告訴編譯器在編譯時(shí)應(yīng)做些什么。DB〔DefineByte〕指令用來告訴DEBUG將單引號內(nèi)的所有ASCII碼放入內(nèi)存中。使用9H功能的字符串必須以$結(jié)尾。用D命令可用來查看DB偽指令將那些內(nèi)容放入內(nèi)存。6.輸入D1001975:0100BA0901B409CD21CD-20756E6465727374......!.underst1975:0110616E64248B46F889-45048B4634006419and$.F..E..F4.d.1975:012089450233C05E5FC9-C300C80400005756.E.3.^_.......WV1975:01306BF80E81C7FE538B-DF8BC2E832FE0BC0k.....S.....2...1975:0140740533C099EB178B-450CE8D4978BF089t.3.....E.......1975:015056FE0BD074EC8B45-0803C68B56FE5E5FV...t..E....V.^_1975:0160C9C3C80200006BD8-0E1975:01708BC2E8FBFD0BC075-098B5EFE8B470CE8.......u..^..G..現(xiàn)在,我們來剖析另一個(gè)程序:由鍵盤輸入任意字符串,然后顯示出來。db20指示DEBUG保存20h個(gè)未用的內(nèi)存空間供緩沖區(qū)使用。輸入A100MOVD*,0116;DS:D*=緩沖區(qū)地址,由DB偽指令確定緩沖區(qū)地址MOVAH,0A;0Ah號功能調(diào)用INT21;鍵盤輸入緩沖區(qū)MOVDL,0A;由于功能Ah在每個(gè)字符串最后加一個(gè)歸位碼〔0Dh由EnterMOVAH,02;產(chǎn)生〕,使光標(biāo)自動回到輸入行的最前端,為了使新輸出的INT21;字符串不會蓋掉原來輸入的字符串,所以利用功能2h加一;個(gè)換行碼(OAh),使得光標(biāo)移到下一行的的最前端。MOVD*,0118;裝入字符串的起始位置MOVAH,09;9h功能遇到$符號才會停頓輸出,故字符串最后必須加上INT21;$,否則9h功能會繼續(xù)將內(nèi)存中的無用數(shù)據(jù)胡亂顯示出來INT20DB20;定義緩沖區(qū)送你一句話:學(xué)匯編切忌心浮氣燥。客套話就不講了。工欲善其事,必先利其器。與其說DEBUG是編譯器,倒不如說它是"直譯器〞,DEBUG的A命令只可將一行匯編指令轉(zhuǎn)成機(jī)器語言,且立刻執(zhí)行。真正編譯器〔MASM〕的運(yùn)作是利用文本編輯器〔EDIT等〕將匯編指令建成一個(gè)獨(dú)立且附加名為.ASM的文本文件,稱源程序。它是MASM程序的輸入局部。MASM將輸入的ASM文件,編譯成.OBJ文件,稱為目標(biāo)程序。OBJ文件僅包含有關(guān)程序各部份要載入何處及如何與其他程序合并的信息,無法直接載入內(nèi)存執(zhí)行。鏈結(jié)程序LINK則可將OBJ文件轉(zhuǎn)換成可載入內(nèi)存執(zhí)行〔E*Ecute〕的E*E文件。還可以用E*E2BIN,將符合條件的E*E文件轉(zhuǎn)成文件〔文件不但占用的內(nèi)存最少,而且運(yùn)行速度最快〕。下面我們用MASM寫一個(gè)與用DEBUG寫的第一個(gè)程序功能一樣的程序。用EDIT編輯一個(gè)SMILE.ASM的源程序文件。源程序DEBUG程序prognamsegmentassumecs:prognamorg100hA100movdl,1movdl,1movah,2movah,2int21hint21int20hint20prognamendsend比擬一下:1.因?yàn)镸ASM會將所有的數(shù)值假設(shè)為十進(jìn)制,而DEBUG則只使用十六進(jìn)制,所以在源程序中,我們必須在有關(guān)數(shù)字后加上代表進(jìn)制的字母,如H代表十六進(jìn)制,D代表十進(jìn)制。假設(shè)是以字母開頭的十六進(jìn)制數(shù)字,還必須在字母前加個(gè)0,以表示它是數(shù),如0AH。2.源程序增加五行表達(dá):prognamsegment與prognamends是成對的,用來告訴MASM及LINK,此程序?qū)⒎旁谝粋€(gè)稱為PROGNAM(PROGramNAMe)的程序段內(nèi),其中段名〔PROGNAM〕可以任取,但其位置必須固定。assumecs:prognam必須在程序的開頭,用來告訴編譯器此程序所在段的位置放在CS存放器中。end用來告訴MASM,程序到此完畢,ORG100H作用相當(dāng)于DEBUG的A100,從偏移量100開場匯編。文件的所有源程序都必須包含這五行,且必須依一樣的次序及位置出現(xiàn),這點(diǎn)東西記下就行,千篇一律。接著,我們用MASM編譯SMILE.ASM。輸入MASMSMILE←不用打入附加名.ASM。Microsoft(R)MacroAssemblerVersion5.10Copyright(C)MicrosoftCorp1981,1988.Allrightsreserved.Objectfilename[SMILE.OBJ]:←是否改動輸出OBJ文件名,如不改就ENTERSourcelisting[NUL.LST]:←是否需要列表文件〔LST〕,不需要就ENTERCross-reference[NUL.CRF]:←是否需要對照文件〔CRF〕,不需要?jiǎng)tENTER50162+403867Bytessymbolspacefree0WarningErrors←警告錯(cuò)誤,表示編譯器對*些語句不理解,通常是輸入錯(cuò)誤。0SevereErrors←嚴(yán)重錯(cuò)誤,會造成程序無法執(zhí)行,通常是語法構(gòu)造錯(cuò)誤。如果沒有一個(gè)錯(cuò)誤存在,即可生成OBJ文件。OBJ中包含的是編譯后的二進(jìn)制結(jié)果,它還無法被DOS載入內(nèi)存中加以執(zhí)行,必須加以鏈結(jié)〔Linking〕。以LINK將OBJ文件〔SMILE.OBJ〕鏈結(jié)成E*E文件〔SMILE.E*E〕時(shí),。1.輸入LINKSMILE←不用附加名OBJMicrosoft(R)OverlayLinkerVersion3.64Copyright(C)MicrosoftCorp1981,1988.Allrightsreserved.RunFile[SMILE.E*E]:←是否改動輸出E*E文件名,如不改就ENTERListFile[NUL.MAP]:←是否需要列表文件〔MAP〕,不需要?jiǎng)tENTERLibraries[.LIB]:←是否需要庫文件,要就鍵入文件名,不要?jiǎng)tENTERLINK:warningL4021:nostacksegment←由于文件不使用堆棧段,所以錯(cuò)誤信息←"nostacksegment"并不影響程序正常執(zhí)行至此已經(jīng)生成E*E文件,我們還須使用E*E2BIN將E*E文件〔SMILE.E*E〕,轉(zhuǎn)換成文件〔SMILE.〕。輸入E*E2BINSMILE產(chǎn)生BIN文件〔SMILE.BIN〕。其實(shí)BIN文件與文件是完全一樣的,但由于DOS只認(rèn)、E*E及BAT文件,所以BIN文件無法被正確執(zhí)行,改名或直接輸入E*E2BINSMILESMILE.即可?,F(xiàn)在,磁盤上應(yīng)該有SMILE.文件了,你只要在提示符號C:>下,直接輸入文件名稱SMILE,就可以執(zhí)行這個(gè)程序了。prognamsegment;定義段assumecs:prognam;把上面定義段的段基址放入CSmovc*,100h;裝入循環(huán)次數(shù)movdl,0;裝入第一個(gè)ASCII碼,隨后每次循環(huán)裝入新碼ne*t:movah,2int21hincdl;INC:遞增指令,每次將數(shù)據(jù)存放器DL內(nèi)的數(shù)值加1loopne*t;循環(huán)指令,執(zhí)行一次,C*減1,直到C*為0,循環(huán)停頓int20hprognamends;段終止end;匯編終止在匯編語言的源程序中,每一個(gè)程序行都包含三項(xiàng)元素start:movdl,1;裝入第一個(gè)ASCII碼,隨后每次循環(huán)裝入新碼標(biāo)識符表達(dá)式注解在原始文件中加上注解可使程序更易理解,便于以后參考。每行注解以";〞與程序行別離。編譯器對注解不予理會,注解的數(shù)據(jù)不會出現(xiàn)在OBJ、E*E或文件中。由于我們在寫源程序時(shí),并不知道每一程序行的地址,所以必須以符號名稱來代表相對地址,稱為"標(biāo)識符〞。我們通常在適當(dāng)行的適當(dāng)位置上,鍵入標(biāo)識符。標(biāo)識符〔label〕最長可達(dá)31個(gè)字節(jié),因此我們在程序中,盡量以簡潔的文字做為標(biāo)識符?,F(xiàn)在,你可以將此ASCII.ASM文件編譯成ASCII.了。1.MASMASCII,2.LINKASCII,3.E*E2BINASCIIASCII.。注意:當(dāng)你以編譯器匯編你設(shè)計(jì)的程序時(shí),常會發(fā)生打字錯(cuò)誤、標(biāo)識符名稱拼錯(cuò)、十六進(jìn)制數(shù)少了h、邏輯錯(cuò)誤等。匯編老手常給新人的忠告是:最好料到自己所寫的程序一定會有些錯(cuò)誤〔別人告訴我的〕;如果第一次執(zhí)行程序后,就得到期望的結(jié)果,你最好還是在檢查一遍,因?yàn)樗赡苁清e(cuò)的。原則上,只要大體的邏輯架構(gòu)正確,查找程序中錯(cuò)誤的過程,與寫程序本身相比甚至更有意思。寫大程序時(shí),最好能分成許多模塊,如此可使程序本身的目的較單純,易于撰寫與查錯(cuò),另外也可讓程序中不同部份之間的界限較清楚,節(jié)省編譯的時(shí)間。如果讀程序有讀不懂的地方最好用紙筆記下有關(guān)存放器、內(nèi)存等內(nèi)容,在紙上慢慢比劃,就豁然開朗了。下面我們將寫一個(gè)能從鍵盤取得一個(gè)十進(jìn)制的數(shù)值,并將其轉(zhuǎn)換成十六進(jìn)制數(shù)值而顯示于屏幕上的"大程序〞。前言:要讓8086執(zhí)行這樣的功能,我們必須先將此問題分解成一連串的步驟,稱為程序規(guī)劃。首先,以流程圖的方式,來確保整個(gè)程序在邏輯上沒有問題〔不用說了吧!什么語言都要有此步驟〕。這種模塊化的規(guī)劃方式,稱之為"由上而下的程序規(guī)劃〞。而在真正寫程序時(shí),卻是從最小的單位模塊〔子程序〕開場,當(dāng)每個(gè)模塊都完成之后,再合并成大程序;這種大處著眼,小處著手的方式稱為"由下而上的程序設(shè)計(jì)〞。我們的第一個(gè)模塊是BINIHE*,其主要用途是從8086的B*存放器中取出二進(jìn)制數(shù),并以十六進(jìn)制方式顯示在屏幕上。注意:子程序如不能獨(dú)立運(yùn)行,實(shí)屬正常。binihe*segmentassumecs:binihe*movch,4;記錄轉(zhuǎn)換后的十六進(jìn)制位數(shù)〔四位〕rotate:movcl,4;利用CL當(dāng)計(jì)數(shù)器,記錄存放器數(shù)位移動次數(shù)rolb*,cl;循環(huán)存放器B*的內(nèi)容,以便依序處理4個(gè)十六進(jìn)制數(shù)moval,bl;把b*低八位bl內(nèi)數(shù)據(jù)轉(zhuǎn)移至alandal,0fh;把無用位清零addal,30h;把AL內(nèi)數(shù)據(jù)加30H,并存入alcmpal,3ah;與3ah比擬jlprintit;小于3ah則轉(zhuǎn)移addal,7h;把AL內(nèi)數(shù)據(jù)加30H,并存入alprintit:movdl,al;把ASCII碼裝入DLmovah,2int21hdecch;ch減一,減到零時(shí),零標(biāo)志置1jnzrotate;JNZ:當(dāng)零標(biāo)志未置1,則跳到指定地址。即:不等,則轉(zhuǎn)移int20h;從子程序退回主程序binihe*endsend利用循環(huán)左移指令ROL循環(huán)存放器B*(B*內(nèi)容將由第二個(gè)子程序提供)的內(nèi)容,以便依序處理4個(gè)十六進(jìn)制數(shù):1.利用CL當(dāng)計(jì)數(shù)器,記錄存放器移位的次數(shù)。2.將B*的第一個(gè)十六進(jìn)制值移到最右邊。利用AND〔邏輯"與〞運(yùn)算:對應(yīng)位都為1時(shí),其結(jié)果為1,其余情況為零〕把不要的部份清零,得到結(jié)果:先將BL值存入AL中,再利用AND以0Fh〔00001111〕將AL的左邊四位清零。由于0到9的ASCII碼為30h到39h,而A到F之ASCII碼為41h到46h,連續(xù)了7h,所以得到結(jié)果:假設(shè)AL之內(nèi)容小于3Ah,則AL值只加30h,否則AL再加7h。ADD指令會將兩個(gè)表達(dá)式相加,其結(jié)果存于左邊表達(dá)式內(nèi)。標(biāo)志存放器〔FlagRegister〕是一個(gè)單獨(dú)的十六位存放器,有9個(gè)標(biāo)志位,*些匯編指令〔大部份是涉及比擬、算術(shù)或邏輯運(yùn)算的指令〕執(zhí)行時(shí),會將相關(guān)標(biāo)志位置1或清0,常碰到的標(biāo)志位有零標(biāo)志〔ZF〕、符號標(biāo)志〔SF〕、溢出標(biāo)志〔OF〕和進(jìn)位標(biāo)志〔CF〕。標(biāo)志位保存了*個(gè)指令執(zhí)行后對它的影響,可用其他相關(guān)指令,查出標(biāo)志的狀態(tài),根據(jù)狀態(tài)產(chǎn)生動作。CMP指令很像減法,是將兩個(gè)表達(dá)式的值相減,但存放器或內(nèi)存的內(nèi)容并未改變,只是相對的標(biāo)志位發(fā)生改變而已:假設(shè)AL值小于3Ah,則正負(fù)號標(biāo)志位會置0,反之則置1。JL指令可解釋為:小于就轉(zhuǎn)移到指定位置,大于、等于則向下執(zhí)行。CMP和JG、JL等條件轉(zhuǎn)移指令一起使用,可以形成程序的分支構(gòu)造,是寫匯編程序常用技巧。第二個(gè)模塊DECIBIN用來接收鍵盤打入的十進(jìn)制數(shù),并將它轉(zhuǎn)換成二進(jìn)制數(shù)放于B*存放器中,供模塊1BINIHE*使用。decibinsegmentassumecs:decibinmovb*,0;B*清零newchar:movah,1;int21h;讀一個(gè)鍵盤輸入符號入al,并顯示subal,30h;al減去30H,結(jié)果存于al中,完成ASCII碼轉(zhuǎn)二進(jìn)制碼jle*it;小于零則轉(zhuǎn)移cmpal,9djge*it;左>右則轉(zhuǎn)移cbw;8位al轉(zhuǎn)換成16位a**chga*,b*;互換a*和b*內(nèi)數(shù)據(jù)movc*,10d;十進(jìn)制數(shù)10入c*mulc*;表達(dá)式的值與a*內(nèi)容相乘,并將結(jié)果存于a**chga*,b*addb*,a*jmpnewchar;無條件轉(zhuǎn)移e*it:int20;回主程序decibinendsendCBW實(shí)際結(jié)果是:假設(shè)AL中的值為正,則AH填入00h;反之,則AH填入FFh。*CHG常用于需要暫時(shí)保存*個(gè)存放器中的內(nèi)容時(shí)。當(dāng)然,還得一個(gè)子程序〔CRLF〕使后顯示的十六進(jìn)制數(shù)不會蓋掉先輸入的十進(jìn)制數(shù)。crlfsegmentassumecs:crlfmovdl,0dh;回車的ASCII碼0DH入DLmovah,2int21hmovdl,0ah;換行的ASSII碼0AH入AHmovah,2int21hint20;回主程序crlfendsend現(xiàn)在我們就可以將BINIHE*、DECIBIN及CRLF等模塊合并成一個(gè)大程序了。首先,我們要將這三個(gè)模塊子程序略加改動。然后,再寫一段程序來調(diào)用每一個(gè)子程序。crlfprocnear;movdl,0dhmovah,2int21hmovdl,0ahmovah,2int21hretcrlfendp類似SEGMENT與ENDS的偽指令,PROC與ENDP也是成對出現(xiàn),用來識別并定義一個(gè)程序。其實(shí),PROC真正的作用只是告訴編譯器:所調(diào)用的程序是屬于近程〔NEAR〕或遠(yuǎn)程〔FAR〕。一般的程序是由DEBUG直接調(diào)用的,所以用INT20返回,用CALL指令所調(diào)用的程序則改用返回指令RET,RET會把控制權(quán)轉(zhuǎn)移到棧頂所指的地址,而該地址是由調(diào)用此程序的CALL指令所放入的。各模塊都搞定了,然后我們把子程序組合起來就大功告成decihe*segment;主程序assumecs:decihe*org100hmovc*,4;循環(huán)次數(shù)入c*;由于子程序要用到c*,故子程序要將c*入棧repeat:calldecibin;調(diào)用十進(jìn)制轉(zhuǎn)二進(jìn)制子程序callcrlf;調(diào)用添加回、換行符子程序callbinihe*;調(diào)用二進(jìn)制轉(zhuǎn)十六進(jìn)制并顯示子程序callcrlflooprepeat;循環(huán)4次,可連續(xù)運(yùn)算4次movah,4ch;調(diào)用DOS21號中斷4c號功能,退出程序,作用跟INT20Hint21H;一樣,但適用面更廣,INT20H退不出時(shí),試一下它decibinprocnearpushc*;將c*壓入堆棧,;┇e*it:popc*;將c*復(fù)原;retdecibinendpbinihe*procnearpushc*┇popc*retbinihe*endpcrlfprocnearpushc*┇popc*retcrlfendpdecihe*endsendCALL指令用來調(diào)用子程序,并將控制權(quán)轉(zhuǎn)移到子程序地址,同時(shí)將CALL的下行一指令地址定為返回地址,并壓入堆棧中。CALL可分為近程〔NEAR〕及遠(yuǎn)程〔FAR〕兩種:1.NEA
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 臨時(shí)過戶合同范例
- 與酒廠合作合同范例
- 全域旅游合同范例
- kty購銷合同范例
- 倉儲搬運(yùn)服務(wù)合同范例
- 農(nóng)莊改造合同范例
- 代工作合同范例
- 中介用代管合同范例
- rot特許經(jīng)營合同范例
- 二零二五年度醫(yī)療行業(yè)勞動合同解除及醫(yī)療待遇協(xié)議
- 化工技術(shù)研發(fā)崗位職責(zé)
- 物流、倉儲危險(xiǎn)源及風(fēng)險(xiǎn)辨識與評價(jià)表
- DG-TJ 08-2367-2021 既有建筑外立面整治設(shè)計(jì)標(biāo)準(zhǔn)
- 五金廠公司績效考核規(guī)則
- 公文流轉(zhuǎn)單(標(biāo)準(zhǔn)模版)
- SJT 05-2023 裝配式建筑標(biāo)準(zhǔn)化產(chǎn)品系列圖集(預(yù)制混凝土樓梯)
- GB/T 6177.2-2000六角法蘭面螺母細(xì)牙
- GB/T 4100-2015陶瓷磚
- 部編人教版語文六年級下冊《2 送元二使安西》課件
- 人教版五年級數(shù)學(xué)下冊第二單元《奇偶性》教案
- 抖音超火看表情符號猜成語課件
評論
0/150
提交評論