匯編語(yǔ)言濃縮教程_第1頁(yè)
匯編語(yǔ)言濃縮教程_第2頁(yè)
匯編語(yǔ)言濃縮教程_第3頁(yè)
匯編語(yǔ)言濃縮教程_第4頁(yè)
匯編語(yǔ)言濃縮教程_第5頁(yè)
已閱讀5頁(yè),還剩17頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、本頁(yè)已使用福昕閱讀器進(jìn)行編輯。 福昕軟件C2005-2010,版權(quán)所有, 僅供試用。匯編語(yǔ)言超濃縮教程摘要對(duì)初學(xué)者而言, 匯編的許多命令太復(fù)雜, 往往學(xué)習(xí)很長(zhǎng)時(shí)間也寫(xiě)不出一個(gè)漂漂亮亮的程序,妨礙我們學(xué)習(xí)匯編的興趣,不少人就此放棄。我個(gè)人的看法是學(xué)匯編,不一定要寫(xiě)程序,寫(xiě)程序確實(shí)不是匯編的強(qiáng)項(xiàng),大家不妨玩玩 DEBUG ,有時(shí) CRACK 出一個(gè)小軟件比完成一個(gè)程序更有成就感“ 哎喲,哥們兒,還搗鼓匯編呢?那東西沒(méi)用,兄弟用 VB" 釣 " 一個(gè) API 就夠你忙活個(gè)十天半月的,還不一定搞出來(lái)。 ” 此君之言倒也不虛,那吾等還有無(wú)必要研他一究呢?(廢話,當(dāng)然有啦!要不然你寫(xiě)這

2、篇文章干嘛。 別急,別急,讓我把這個(gè)中原委慢慢道來(lái):一、所有電腦語(yǔ)言寫(xiě)出的程序運(yùn)行時(shí)在內(nèi)存中都以機(jī)器碼方式存儲(chǔ), 機(jī)器碼可以被比較準(zhǔn)確的翻譯成匯編語(yǔ)言,這是因?yàn)閰R編語(yǔ)言兼容性最好,故幾乎所有跟蹤、調(diào)試工具(包括 WIN95/98下都是以匯編示人的,如果閣下對(duì) CRACK 頗感興趣 ;二、匯編直接與硬件打交道,如果你想搞通程序在執(zhí)行時(shí)在電腦中的來(lái)龍去脈, 也就是搞清電腦每個(gè)組成部分究竟在干什么、 究竟怎么干?一個(gè)真正的硬件發(fā)燒友, 不懂這些可不行。 三、 如今玩 DOS 的多是 “ 高手 ” ,如能像吾一樣混入(我不是高手 “ 高手 ” 內(nèi)部,不僅可以從 “ 高手 ” 朋友那兒套些黑客級(jí) “ 機(jī)

3、密 ” ,還可以自詡 “ 高手 ” 盡情享受強(qiáng)烈的虛榮感 -#$%&“ 醒醒 !”對(duì)初學(xué)者而言, 匯編的許多命令太復(fù)雜, 往往學(xué)習(xí)很長(zhǎng)時(shí)間也寫(xiě)不出一個(gè)漂漂亮亮的程序, 以致妨礙了我們學(xué)習(xí)匯編的興趣,不少人就此放棄。所以我個(gè)人看法學(xué)匯編,不一定要寫(xiě)程序,寫(xiě)程序確實(shí)不是匯編的強(qiáng)項(xiàng),大家不妨玩玩 DEBUG ,有時(shí) CRACK 出一個(gè)小軟件比完成一個(gè)程序更有成就感(就像學(xué)電腦先玩游戲一樣 。某些高深的指令事實(shí)上只對(duì)有經(jīng)驗(yàn)的匯編程序員有用,對(duì)我們而言,太過(guò)高深了。為了使學(xué)習(xí)匯編語(yǔ)言有個(gè)好的開(kāi)始,你必須要先排除那些華麗復(fù)雜的命令,將注意力集中在最重要的幾個(gè)指令上(CMP LOOP MOVJNZ

4、。但是想在啰里吧嗦的教科書(shū)中完成上述目標(biāo),談何容易,所以本人整理了這篇超濃縮(用 WINZIP 、 WINRAR 依次壓迫,嘿嘿! 教程。大言不慚的說(shuō),看通本文,你完全可以 “ 不經(jīng)意 ” 間在前輩或是后生賣(mài)弄一下 DEBUG ,很有成就感的,試試看!那么 這個(gè)接下來(lái)呢? Here we go ! (閱讀時(shí)看不懂不要緊,下文必有分解因?yàn)閰R編是通過(guò) CPU 和內(nèi)存跟硬件對(duì)話的,所以我們不得不先了解一下 CPU 和內(nèi)存:(關(guān)于數(shù)的進(jìn)制問(wèn)題在此不提CPU是可以執(zhí)行電腦所有算術(shù)邏輯運(yùn)算與基本 I/O控制功能的一塊芯片。一種匯編語(yǔ)言只能用于特定的 CPU 。也就是說(shuō),不同的 CPU 其匯編語(yǔ)言的指令語(yǔ)法

5、亦不相同。個(gè)人電腦由 1981年推出至今,其 CPU 發(fā)展過(guò)程為:8086802868038680486PENTIUM ,還有 AMD 、 CYRIX 等旁支。后面兼容前面 CPU 的功能,只不過(guò)多了些指令(如多能奔騰的 MMX 指令集 、增大了寄存器(如 386的 32位 EAX 、增多了寄存器(如 486的FS 。為確保匯編程序可以適用于各種機(jī)型,所以推薦使用 8086匯編語(yǔ)言,其兼容性最佳。本文所提均為 8086匯編語(yǔ)言。寄存器(Register 是 CPU 內(nèi)部的元件,所以在寄存器之間的數(shù)據(jù)傳送非???。用途:1. 可將寄存器內(nèi)的數(shù)據(jù)執(zhí)行算術(shù)及邏輯運(yùn)算。 2. 存于寄存器內(nèi)的地址可用來(lái)指

6、向內(nèi)存的某個(gè)位置,即尋址。 3. 可以用來(lái)讀寫(xiě)數(shù)據(jù)到電腦的周邊設(shè)備。 8086有 8本頁(yè)已使用福昕閱讀器進(jìn)行編輯。 福昕軟件(C2005-2010,版權(quán)所有, 僅供試用。個(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è)段寄存器,專(zhuān)門(mén)用來(lái)保存段地址:CS(Code Segment :代碼段寄存器;DS(Data Segmen

7、t :數(shù)據(jù)段寄存器;SS(Stack Segment :堆棧段寄存器;ES(Extra Segment :附加段寄存器。當(dāng)一個(gè)程序要執(zhí)行時(shí),就要決定程序代碼、數(shù)據(jù)和堆棧各要用到內(nèi)存的哪些位置,通過(guò)設(shè)定段寄存器 CS , DS , SS 來(lái)指向這些起始位置。通常是將 DS 固定,而根據(jù)需要修改 CS 。所以,程序可以在可尋址空間小于 64K 的情況下被寫(xiě)成任意大小。 所以,程序和其數(shù)據(jù)組合起來(lái)的大小,限制在 DS 所指的 64K 內(nèi),這就是COM 文件不得大于 64K 的原因。 8086以內(nèi)存做為戰(zhàn)場(chǎng),用寄存器做為軍事基地,以加速工作。除了前面所提的寄存器外,還有一些特殊功能的寄存器:IP (I

8、ntruction Pointer :指令指針寄存器,與 CS 配合使用,可跟蹤程序的執(zhí)行過(guò)程; SP (Stack Pointer :堆棧指針, 與SS 配合使用,可指向目前的堆棧位置。 BP (Base Pointer :基址指針寄存器,可用作 SS 的一個(gè)相對(duì)基址位置; SI (Source Index :源變址寄存器可用來(lái)存放相對(duì)于 DS 段之源變址指針; DI (Destination Index :目的變址寄存器,可用來(lái)存放相對(duì)于 ES 段之目的變址指針。還有一個(gè)標(biāo)志寄存器 FR (Flag Register , 有九個(gè)有意義的標(biāo)志,將在下文用到時(shí)詳細(xì)說(shuō)明。內(nèi)存是電腦運(yùn)作中的關(guān)鍵部

9、分, 也是電腦在工作中儲(chǔ)存信息的地方。 內(nèi)存組織有許多可存放數(shù)值的儲(chǔ)存位置,叫 “ 地址 ” 。 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è)地

10、址。如:2222(段基址 :3333(偏移量 ,其實(shí)際的 20位地址值為:25553。除了上述營(yíng)養(yǎng)要充分吸收外,你還要知道什么是 DOS 、 BIOS 功能調(diào)用,簡(jiǎn)單的說(shuō),功能調(diào)用類(lèi)似于 WIN95API ,相當(dāng)于子程序。匯編寫(xiě)程序已經(jīng)夠要命了,如果不用 MS 、 IBM 的子程序,這日子真是沒(méi)法過(guò)了(關(guān)于功能調(diào)用詳見(jiàn)電腦愛(ài)好者 98年 11期 。編寫(xiě)匯編語(yǔ)言有兩種主要的方法:1. 使用 MASM 或 TASM 等編譯器; 2. 使用除錯(cuò)程序 DEBUG.COM 。 DEBUG 其實(shí)并不能算是一個(gè)編譯器,它的主要用途在于除錯(cuò),即修正匯編程序中的錯(cuò)誤。不過(guò),也可以用來(lái)寫(xiě)短的匯編程序,尤其對(duì)初學(xué)者

11、而言, DEBUG 更是最佳的入門(mén)工具。因?yàn)?DEBUG 操作容易:只要鍵入 DEBUG 回車(chē), A 回車(chē)即可進(jìn)行匯編,過(guò)程簡(jiǎn)單,而使用編譯器時(shí),必須用到文本編輯器、編譯器本身、 LINK 以及 EXE2BIN 等程序,其中每一個(gè)程序都必須用到一系列相當(dāng)復(fù)雜的命令才能工作,而且用編譯器處理源程序, 必須加入許多與指令語(yǔ)句無(wú)關(guān)的指示性語(yǔ)句,以供編譯器識(shí)別,使用 DEBUG 可以避免一開(kāi)始就碰到許多難以理解的程序行。 DEBUG 除了能夠匯編程序之外, 還可用來(lái)檢查和修改內(nèi)存位置、載入儲(chǔ)存和執(zhí)行程序、以及檢查和修改寄存器,換句話說(shuō), DEBUG 是為了讓我們接觸硬件而設(shè)計(jì)的。 (8086常用指令用

12、法將在每個(gè)匯編程序中講解,限于篇幅,不可能將所有指令列出 。DEBUG 的的 A 命令可以匯編出簡(jiǎn)單的 COM 文件,所以 DEBUG 編寫(xiě)的程序一定要由地址 100h (COM 文件要求開(kāi)始才合法。 FOLLOW ME , SETP BY SETP (步步回車(chē) :輸入 A100; 從 DS :100開(kāi)始匯編2. 輸入 MOV DL,1; 將數(shù)值 01h 裝入 DL 寄存器3. 輸入 MOV AH,2; 將數(shù)值 02h 裝入 DL 寄存器4. 輸入 INT 21; 調(diào)用 DOS 21號(hào)中斷 2號(hào)功能,用來(lái)逐個(gè)顯示裝入 DL 的字符5. 輸入 INT 20; 調(diào)用 DOS 20號(hào)中斷,終止程序,

13、將控制權(quán)交回給 DEBUG6. 請(qǐng)按 Enter 鍵7. 現(xiàn)在已將匯編語(yǔ)言程序放入內(nèi)存中了,輸入 G(運(yùn)行 8. 出現(xiàn)結(jié)果:輸出一個(gè)符號(hào)。 輸出結(jié)果其實(shí)不是它,因 WORD97無(wú)法顯示原結(jié)果,故找一贗品將就著。 Program terminated normally我們可以用U命令將十六進(jìn)制的機(jī)器碼反匯編(Unassemble 成匯編指令。 你將發(fā)現(xiàn)每 一行右邊的匯編指令就是被匯編成相應(yīng)的機(jī)器碼,而 8086實(shí)際上就是以機(jī)器碼來(lái)執(zhí)行程序。1. 輸入 U100,1061FED:0100B201MOV DL,011FED:0102B402MOV AH,021FED:0104CD21INT 211F

14、ED:0106CD20INT 20DEBUG 可以用R命令來(lái)查看、改變寄存器內(nèi)容。 CS :IP 寄存器,保存了將執(zhí)行指令 地址。1. 輸入 RAX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000DS=1FEDES=1FEDSS=1FEDCS=1FEDIP=0100NV UP EI PL NZ NA PO NC1FED:0100B201MOV DL,01當(dāng)程序由 DS :100開(kāi)始執(zhí)行,那么終止程序時(shí), DEBUG 會(huì)自動(dòng)將 IP 內(nèi)容重新設(shè)定為 100。當(dāng)你要將此程序做成一個(gè)獨(dú)立的可執(zhí)行文件,則可以用N命令對(duì)該程序命名。但一定 要為

15、 COM 文件,否則無(wú)法以 DEBUG 載入。輸入 N SMILE.COM ;我們得告訴 DEBUG 程序長(zhǎng)度:程序從 100開(kāi)始到 106,故占用 7;字節(jié)。我們利用 BX 存放長(zhǎng)度值高位部分,而以 CX 存放低位部分。2. 輸入 RBX ;查看 BX 寄存器的內(nèi)容,本程序只有 7個(gè)字節(jié),故本步可省略3. 輸入 RCX ;查看 CX 寄存器的內(nèi)容4. 輸入 7;程序的字節(jié)數(shù)5. 輸入 W ;用W命令將該程序?qū)懭?Write 磁盤(pán)中修行至此,我們便可以真正接觸 8086匯編指令了。 當(dāng)我們寫(xiě)匯編語(yǔ)言程序的時(shí)候,通 常不會(huì)直接將機(jī)器碼放入內(nèi)存中,而是打入一串助記符號(hào)(Mnemonic Symbo

16、ls ,這些符號(hào) 比十六進(jìn)制機(jī)器碼更容易記住, 此之謂匯編指令。 助記符號(hào), 告訴 CPU 應(yīng)執(zhí)行何種運(yùn)算。 也 就是說(shuō),助憶符號(hào)所構(gòu)成的匯編語(yǔ)言是為人設(shè)計(jì)的,而機(jī)器語(yǔ)言是對(duì) PC 設(shè)計(jì)的?,F(xiàn)在,我們?cè)賮?lái)剖析一個(gè)可以將所有 ASCII 碼顯示出來(lái)的程序。1. 輸入 DEBUG2. 輸入 A1003.輸入 MOV CX,0100;裝入循環(huán)次數(shù)MOV DL,00;裝入第一個(gè) ASCII 碼,隨后每次循環(huán)裝入新碼MOV AH,02INT 21INC DL ; INC :遞增指令,每次將數(shù)據(jù)寄存器 DL 內(nèi)的數(shù)值加 1LOOP 0105; LOOP :循環(huán)指令,每執(zhí)行一次 LOOP , CX 值減 1

17、,并跳;到循環(huán)的起始地址 105,直到 CX 為 0,循環(huán)停止INT 204. 輸入 G 即可顯示所有 ASCII 碼當(dāng)我們想任意顯示字符串,如:UNDERSTAND ?,則可以使用 DOS21H 號(hào)中斷 9H 號(hào) 功能。輸入下行程序,存盤(pán)并執(zhí)行看看:1. 輸入 A100MOV DX,109; DS:DX=字符串的起始地址MOV AH,9; DOS 的 09h 功能調(diào)用INT 21;字符串輸出INT 20DB 'UNDERSTAND ? $'定義字符串在匯編語(yǔ)言中,有兩種不同的指令:1. 正規(guī)指令:如 MOV 等,是屬于 CPU 的指令, 用來(lái)告訴 CPU 在程序執(zhí)行時(shí)應(yīng)做些什

18、么, 所以它會(huì)以運(yùn)算碼 (OP-code 的方式存入內(nèi)存中; 2. 偽指令:如 DB 等,是屬于 DEBUG 等編譯器的指令,用來(lái)告訴編譯器在編譯時(shí)應(yīng)做些什 么。 DB (Define Byte 指令用來(lái)告訴 DEBUG 將單引號(hào)內(nèi)的所有 ASCII 碼放入內(nèi)存中。 使 用 9H 功能的字符串必須以 $結(jié)尾。用D命令可用來(lái)查看 DB 偽指令將那些內(nèi)容放入內(nèi)存。6. 輸入 D1001975:0100BA 0901B409CD 21CD-20756E 6465727374.!. underst1975:0110616E 64248B 46F889-45048B 4634006419and$.F.E

19、.F4.d.1975:012089450233C05E 5F C9-C300C80400005756.E.3._.WV1975:01306B F80E 81C7FE 538B-DF 8B C2E832FE 0B C0k.S.2.1975:0140740533C099EB 178B-450C E8D4978B F089t.3.E.1975:015056FE 0B D074EC 8B 45-0803C68B 56FE 5E 5F V.t.E.V._1975:0160C9C3C80200006B D8-0E 81C3FE 53895E FE.k.S.1975:01708B C2E8FB FD 0B

20、C075-098B 5E FE 8B 470C E8.u.G.現(xiàn)在,我們來(lái)剖析另一個(gè)程序:由鍵盤(pán)輸入任意字符串,然后顯示出來(lái)。 db 20指示 DEBUG 保留 20h 個(gè)未用的內(nèi)存空間供緩沖區(qū)使用。輸入 A100MOV DX,0116; DS:DX=緩沖區(qū)地址,由 DB 偽指令確定緩沖區(qū)地址MOV AH,0A ; 0Ah 號(hào)功能調(diào)用INT 21;鍵盤(pán)輸入緩沖區(qū)MOV DL,0A ;由于功能 Ah 在每個(gè)字符串最后加一個(gè)歸位碼(0Dh 由 EnterMOV AH,02;產(chǎn)生 ,使光標(biāo)自動(dòng)回到輸入行的最前端,為了使新輸出的INT 21;字符串不會(huì)蓋掉原來(lái)輸入的字符串,所以利用功能 2h 加一;個(gè)

21、換行碼 (OAh,使得光標(biāo)移到下一行的的最前端。MOV DX,0118;裝入字符串的起始位置MOV AH,09; 9h 功能遇到 $符號(hào)才會(huì)停止輸出,故字符串最后必須加上INT 21; $,否則 9h 功能會(huì)繼續(xù)將內(nèi)存中的無(wú)用數(shù)據(jù)胡亂顯示出來(lái)INT 20DB 20;定義緩沖區(qū)送你一句話:學(xué)匯編切忌心浮氣燥??吞自捑筒恢v了。工欲善其事,必先利其器。與其說(shuō) DEBUG 是編譯器,倒不如說(shuō)它 是 “ 直譯器 ” , DEBUG 的 A 命令只可將一行匯編指令轉(zhuǎn)成機(jī)器語(yǔ)言,且立刻執(zhí)行。真正編譯 器 (MASM 的運(yùn)作是利用文本編輯器 (EDIT 等 將匯編指令建成一個(gè)獨(dú)立且附加名為 .ASM 的文本文

22、件,稱(chēng)源程序。它是 MASM 程序的輸入部分。 MASM 將輸入的 ASM 文件,編譯 成 .OBJ 文件,稱(chēng)為目標(biāo)程序。 OBJ 文件僅包含有關(guān)程序各部份要載入何處及如何與其他程 序合并的信息,無(wú)法直接載入內(nèi)存執(zhí)行。鏈結(jié)程序 LINK 則可將 OBJ 文件轉(zhuǎn)換成可載入內(nèi) 存執(zhí)行(EXEcute 的 EXE 文件。還可以用 EXE2BIN ,將符合條件的 EXE 文件轉(zhuǎn)成 COM 文件(COM 文件不但占用的內(nèi)存最少,而且運(yùn)行速度最快 。下面我們用 MASM 寫(xiě)一個(gè)與用 DEBUG 寫(xiě)的第一個(gè)程序功能一樣的程序。用 EDIT 編輯一個(gè) SMILE.ASM 的源程序文件。源程序 DEBUG 程序

23、prognam segmentassume cs:prognamorg 100h A100mov dl,1mov dl,1mov ah,2mov ah,2int 21h int 21int 20h int 20prognam endsend比較一下:1. 因?yàn)?MASM 會(huì)將所有的數(shù)值假設(shè)為十進(jìn)制,而 DEBUG 則只使用十六進(jìn) 制,所以在源程序中,我們必須在有關(guān)數(shù)字后加上代表進(jìn)制的字母,如 H 代表十六進(jìn)制, D 代表十進(jìn)制。若是以字母開(kāi)頭的十六進(jìn)制數(shù)字,還必須在字母前加個(gè) 0,以表示它是數(shù), 如 0AH 。 2. 源程序增加五行敘述:prognam segment 與 prognam en

24、ds 是成對(duì)的,用來(lái)告訴 MASM 及 LINK ,此程序?qū)⒎旁谝粋€(gè)稱(chēng)為 PROGNAM(PROGramNAMe 的程序段內(nèi),其中 段名(PROGNAM 可以任取,但其位置必須固定。 assume cs:prognam必須在程序的開(kāi)頭, 用來(lái)告訴編譯器此程序所在段的位置放在 CS 寄存器中。 end 用來(lái)告訴 MASM ,程序到此結(jié) 束 , ORG 100H 作用相當(dāng)于 DEBUG 的 A100, 從偏移量 100開(kāi)始匯編。 COM 文件的所有源程 序都必須包含這五行,且必須依相同的次序及位置出現(xiàn),這點(diǎn)東西記下就行,千篇一律。 接 著,我們用 MASM 編譯 SMILE.ASM 。輸入 MAS

25、M SMILE 不用打入附加名 .ASM 。Microsoft (RMacro Assembler Version 5.10Copyright (CMicrosoft Corp 1981, 1988. All rights reserved.Object filename SMILE.OBJ: 是否改動(dòng)輸出 OBJ 文件名,如不改就 ENTERSource listing NUL.LST: 是否需要列表文件(LST ,不需要就 ENTERCross-reference NUL.CRF: 是否需要對(duì)照文件(CRF ,不需要?jiǎng)t ENTER50162+403867Bytes symbol space

26、 free0Warning Errors 警告錯(cuò)誤,表示編譯器對(duì)某些語(yǔ)句不理解,通常是輸入錯(cuò)誤。0Severe Errors 嚴(yán)重錯(cuò)誤,會(huì)造成程序無(wú)法執(zhí)行,通常是語(yǔ)法結(jié)構(gòu)錯(cuò)誤。如果沒(méi)有一個(gè)錯(cuò)誤存在,即可生成 OBJ 文件。 OBJ 中包含的是編譯后的二進(jìn)制結(jié)果, 它還無(wú)法被 DOS 載入內(nèi)存中加以執(zhí)行,必須加以鏈結(jié)(Linking 。以 LINK 將 OBJ 文件 (SMILE.OBJ 鏈結(jié)成 EXE 文件(SMILE.EXE 時(shí), 。1. 輸入 LINK SMILE 不用附加名 OBJMicrosoft (ROverlay Linker Version 3.64Copyright (CMic

27、rosoft Corp 1981, 1988. All rights reserved.Run File SMILE.EXE: 是否改動(dòng)輸出 EXE 文件名,如不改就 ENTERList File NUL.MAP: 是否需要列表文件(MAP ,不需要?jiǎng)t ENTERLibraries .LIB: 是否需要庫(kù)文件,要就鍵入文件名,不要?jiǎng)t ENTERLINK :warning L4021:no stack segment 由于 COM 文件不使用堆棧段,所以錯(cuò)誤信 息"no stack segment" 并不影響程序正常執(zhí)行至此已經(jīng)生成 EXE 文件,我們還須使用 EXE2BIN

28、 將 EXE 文件(SMILE.EXE ,轉(zhuǎn)換 成 COM 文件(SMILE.COM 。輸入 EXE2BIN SMILE 產(chǎn)生 BIN 文件(SMILE.BIN 。其實(shí) BIN 文件與 COM 文件是完全相同的,但由于 DOS 只認(rèn) COM 、 EXE 及 BAT 文件,所以 BIN 文件無(wú)法被正確執(zhí)行,改名或直接輸入 EXE2BIN SMILE SMILE.COM 即可?,F(xiàn)在, 磁 盤(pán)上應(yīng)該有 SMILE.COM 文件了, 你只要在提示符號(hào) C :>下, 直接輸入文件名稱(chēng) SMILE , 就可以執(zhí)行這個(gè)程序了。你是否覺(jué)得用編譯器產(chǎn)生程序的方法,比 DEBUG 麻煩多了!以小程序而言,的

29、確是 如此,但對(duì)于較大的程序,你就會(huì)發(fā)現(xiàn)其優(yōu)點(diǎn)了。我們?cè)賹?ASCII 程序以編譯器方式再做 一次,看看有無(wú)差異。首先,用 EDIT.COM 建立 ASCII.ASM 文件。prognam segment ; 定義段assume cs:prognam; 把上面定義段的段基址放入 CSmov cx,100h ; 裝入循環(huán)次數(shù)mov dl,0; 裝入第一個(gè) ASCII 碼,隨后每次循環(huán)裝入新碼next:mov ah,2int 21hinc dl ;INC :遞增指令,每次將數(shù)據(jù)寄存器 DL 內(nèi)的數(shù)值加 1loop next ; 循環(huán)指令,執(zhí)行一次, CX 減 1,直到 CX 為 0,循環(huán)停止int

30、 20hprognam ends ; 段終止end ; 匯編終止在匯編語(yǔ)言的源程序中,每一個(gè)程序行都包含三項(xiàng)元素:start:mov dl,1;裝入第一個(gè) ASCII 碼,隨后每次循環(huán)裝入新碼標(biāo)識(shí)符 表達(dá)式 注解在原始文件中加上注解可使程序更易理解,便于以后參考。每行注解以 “ ; ” 與程序行分 離。 編譯器對(duì)注解不予理會(huì),注解的數(shù)據(jù)不會(huì)出現(xiàn)在 OBJ 、 EXE 或 COM 文件中。由于我們 在寫(xiě)源程序時(shí), 并不知道每一程序行的地址, 所以必須以符號(hào)名稱(chēng)來(lái)代表相對(duì)地址, 稱(chēng)為 “ 標(biāo) 識(shí)符 ” 。 我們通常在適當(dāng)行的適當(dāng)位置上, 鍵入標(biāo)識(shí)符。 標(biāo)識(shí)符 (label 最長(zhǎng)可達(dá) 31個(gè)字節(jié),

31、因此我們?cè)诔绦蛑?盡量以簡(jiǎn)潔的文字做為標(biāo)識(shí)符?,F(xiàn)在,你可以將此 ASCII.ASM 文件編譯成 ASCII.COM 了。 1.MASM ASCII , 2.LINK ASCII , 3.EXE2BIN ASCII ASCII.COM 。注意:當(dāng)你以編譯器匯編你設(shè)計(jì)的程序時(shí),常會(huì)發(fā)生打字錯(cuò)誤、標(biāo)識(shí)符名稱(chēng)拼錯(cuò)、十六 進(jìn)制數(shù)少了h、 邏輯錯(cuò)誤等。 匯編老手常給新人的忠告是:最好料到自己所寫(xiě)的程序一定會(huì) 有些錯(cuò)誤(別人告訴我的 ;如果第一次執(zhí)行程序后,就得到期望的結(jié)果,你最好還是在檢 查一遍,因?yàn)樗赡苁清e(cuò)的。原則上,只要大體的邏輯架構(gòu)正確,查找程序中錯(cuò)誤的過(guò)程, 與寫(xiě)程序本身相比甚至更有意思。 寫(xiě)大

32、程序時(shí), 最好能分成許多模塊, 如此可使程序本身的 目的較單純, 易于撰寫(xiě)與查錯(cuò), 另外也可讓程序中不同部份之間的界限較清楚, 節(jié)省編譯的 時(shí)間。 如果讀程序有讀不懂的地方最好用紙筆記下有關(guān)寄存器、 內(nèi)存等內(nèi)容, 在紙上慢慢比 劃,就豁然開(kāi)朗了。 下面我們將寫(xiě)一個(gè)能從鍵盤(pán)取得一個(gè)十進(jìn)制的數(shù)值,并將其轉(zhuǎn)換 成十六進(jìn)制數(shù)值而顯示于屏幕上的 “ 大程序 ” 。前言:要讓 8086執(zhí)行這樣的功能,我們必須先 將此問(wèn)題分解成一連串的步驟,稱(chēng)為程序規(guī)劃。首先, 以流程圖的方式,來(lái)確保整個(gè)程序在 邏輯上沒(méi)有問(wèn)題 (不用說(shuō)了吧! 什么語(yǔ)言都要有此步驟 。 這種模塊化的規(guī)劃方式, 稱(chēng)之為 “ 由 上而下的程序規(guī)

33、劃 ” 。而在真正寫(xiě)程序時(shí),卻是從最小的單位模塊(子程序開(kāi)始,當(dāng)每個(gè) 模塊都完成之后,再合并成大程序;這種大處著眼,小處著手的方式稱(chēng)為 “ 由下而上的程序 設(shè)計(jì) ” 。我們的第一個(gè)模塊是 BINIHEX ,其主要用途是從 8086的 BX 寄存器中取出二進(jìn)制數(shù), 并以十六進(jìn)制方式顯示在屏幕上。注意:子程序如不能獨(dú)立運(yùn)行,實(shí)屬正常。binihex segmentassume cs:binihexmov ch,4; 記錄轉(zhuǎn)換后的十六進(jìn)制位數(shù)(四位rotate:mov cl,4; 利用 CL 當(dāng)計(jì)數(shù)器,記錄寄存器數(shù)位移動(dòng)次數(shù)rol bx,cl ; 循環(huán)寄存器 BX 的內(nèi)容,以便依序處理 4個(gè)十六進(jìn)制

34、數(shù)mov al,bl ; 把 bx 低八位 bl 內(nèi)數(shù)據(jù)轉(zhuǎn)移至 aland al,0fh ; 把無(wú)用位清零add al,30h ; 把 AL 內(nèi)數(shù)據(jù)加 30H ,并存入 alcmp al,3ah ; 與 3ah 比較jl printit ; 小于 3ah 則轉(zhuǎn)移add al,7h ; 把 AL 內(nèi)數(shù)據(jù)加 30H ,并存入 alprintit:movdl,al ; 把 ASCII 碼裝入 DLmov ah,2int 21hdec ch ;ch 減一,減到零時(shí),零標(biāo)志置 1jnz rotate ;JNZ :當(dāng)零標(biāo)志未置 1,則跳到指定地址。即:不等,則轉(zhuǎn)移int 20h ; 從子程序退回主程序bi

35、nihex endsend利用循環(huán)左移指令 ROL 循環(huán)寄存器 BX(BX內(nèi)容將由第二個(gè)子程序提供 的內(nèi)容,以便 依序處理 4個(gè)十六進(jìn)制數(shù) :1.利用 CL 當(dāng)計(jì)數(shù)器,記錄寄存器移位的次數(shù)。 2. 將 BX 的第一個(gè) 十六進(jìn)制值移到最右邊。利用 AND (邏輯 “ 與 ” 運(yùn)算:對(duì)應(yīng)位都為1時(shí),其結(jié)果為1,其余 情況為零把不要的部份清零,得到結(jié)果:先將 BL 值存入 AL 中,再利用 AND 以 0Fh (00001111 將 AL 的左邊四位清零。 由于0到9的 ASCII 碼為 30h 到 39h , 而A到F之 ASCII 碼為 41h 到 46h ,間斷了 7h ,所以得到結(jié)果:若 A

36、L 之內(nèi)容小于 3Ah ,則 AL 值只加 30h ,否則 AL 再加 7h 。 ADD 指令會(huì)將兩個(gè)表達(dá)式相加, 其結(jié)果存于左邊表達(dá)式內(nèi)。 標(biāo)志寄存器 (Flag Register 是一個(gè)單獨(dú)的十六位寄存器,有 9個(gè)標(biāo)志位,某些匯編指令(大部份是涉及比較、 算術(shù)或邏輯運(yùn)算的指令執(zhí)行時(shí),會(huì)將相關(guān)標(biāo)志位置 1或清 0, 常碰到的標(biāo)志位有零標(biāo)志 (ZF 、符號(hào)標(biāo)志(SF 、溢出標(biāo)志(OF 和進(jìn)位標(biāo)志(CF 。 標(biāo)志位保存了某個(gè)指令執(zhí)行 后對(duì)它的影響,可用其他相關(guān)指令,查出標(biāo)志的狀態(tài),根據(jù)狀態(tài)產(chǎn)生動(dòng)作。 CMP 指令很像 減法, 是將兩個(gè)表達(dá)式的值相減, 但寄存器或內(nèi)存的內(nèi)容并未改變, 只是相對(duì)的標(biāo)

37、志位發(fā)生 改變而已:若 AL 值小于 3Ah ,則正負(fù)號(hào)標(biāo)志位會(huì)置 0,反之則置 1。 JL 指令可解釋為:小于就轉(zhuǎn)移到指定位置,大于、等于則向下執(zhí)行。 CMP 和 JG 、 JL 等條件轉(zhuǎn)移指令一起使 用,可以形成程序的分支結(jié)構(gòu),是寫(xiě)匯編程序常用技巧。第二個(gè)模塊 DECIBIN 用來(lái)接收鍵盤(pán)打入的十進(jìn)制數(shù),并將它轉(zhuǎn)換成二進(jìn)制數(shù)放于 BX 寄存器中,供模塊 1BINIHEX 使用。decibin segmentassume cs:decibinmov bx,0;BX 清零newchar:movah,1;int 21h ; 讀一個(gè)鍵盤(pán)輸入符號(hào)入 al ,并顯示sub al,30h ;al 減去

38、30H ,結(jié)果存于 al 中,完成 ASCII 碼轉(zhuǎn)二進(jìn)制碼jl exit ; 小于零則轉(zhuǎn)移cmp al,9djg exit ; 左 >右則轉(zhuǎn)移cbw ;8位 al 轉(zhuǎn)換成 16位 axxchg ax,bx ; 互換 ax 和 bx 內(nèi)數(shù)據(jù)mov cx,10d ; 十進(jìn)制數(shù) 10入 cxmul cx ; 表達(dá)式的值與 ax 內(nèi)容相乘,并將結(jié)果存于 axxchg ax,bxadd bx,axjmp newchar ; 無(wú)條件轉(zhuǎn)移exit:int 20; 回主程序decibin endsendCBW 實(shí)際結(jié)果是 :若 AL 中的值為正, 則 AH 填入 00h ; 反之, 則 AH 填入 FFh 。 XCHG 常用于需要暫時(shí)保留某個(gè)寄存器中的內(nèi)容時(shí)。當(dāng)然,還得一個(gè)子程序(CRLF 使后顯示的十六進(jìn)制數(shù)不會(huì)蓋掉先輸入的十進(jìn)制數(shù)。crlf segmentassume cs:crlfmov dl,0dh ; 回車(chē)的 ASCII 碼 0DH 入 DLmov ah,2int 21hmov dl,0ah ; 換行的 ASSII 碼 0AH 入 AHmov ah,2int 21hint

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論