匯編基礎(chǔ)入門知識(shí)_第1頁(yè)
匯編基礎(chǔ)入門知識(shí)_第2頁(yè)
匯編基礎(chǔ)入門知識(shí)_第3頁(yè)
匯編基礎(chǔ)入門知識(shí)_第4頁(yè)
匯編基礎(chǔ)入門知識(shí)_第5頁(yè)
已閱讀5頁(yè),還剩31頁(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、匯編基礎(chǔ)入門知識(shí) 最近想初步了解一下匯編的內(nèi)容,在網(wǎng)上搜了搜,發(fā)現(xiàn)一篇寫(xiě)得很不錯(cuò)的文章,特地轉(zhuǎn)過(guò)來(lái)留存。寫(xiě)得淺顯易懂,而且加入了很多個(gè)人的見(jiàn)解,比書(shū)上寫(xiě)的好懂多了。比較欽佩作者,可惜找了半天沒(méi)有找到這篇文章的原作者是誰(shuí)。轉(zhuǎn)載地址: 學(xué)習(xí)匯編前你應(yīng)該知道的知識(shí) 1、匯編需要什么工具和程序,到哪里下載? 目前階段,匯編程序僅需要兩個(gè)程序就夠了。masm.exe,link.exe。 前者是編譯程序,后者是鏈接程序。另外,為了驗(yàn)證和調(diào)試程序,還需要一個(gè)程序debug.exe,該程序由windows本身就提供。 將二者下載后,放到某一個(gè)目錄中(任意目錄都可以),考慮到很多命令需要通過(guò)鍵盤(pán)敲入,所以建議你

2、不要把文件放入到長(zhǎng)文件名目錄、中文目錄或很深的目錄中。比如你可以建一個(gè)“d:masm”目錄,并建議此后的程序都放這個(gè)目錄,此后稱這個(gè)目錄為匯編目錄。 2、學(xué)習(xí)匯編需要有哪些編程方面的知識(shí)? 沒(méi)有任何編程方面的知識(shí),學(xué)習(xí)此語(yǔ)言等于緣木求魚(yú),所以請(qǐng)放棄學(xué)習(xí)的想法。一般來(lái)說(shuō)至少要知道如下幾點(diǎn): *)程序的運(yùn)行邏輯結(jié)構(gòu)有順序(按語(yǔ)句依次執(zhí)行)、分支結(jié)構(gòu)(if.then.else.),循環(huán)結(jié)構(gòu)(for.next)三種結(jié)構(gòu)。 *)知道什么是子程序,什么是調(diào)用。 *)匯編程序員的視角。不同編程視角編程要求是不一樣的。比如刪除文件: 用戶的視角是找到“刪除”按鈕或菜單,然后單擊一下即可。 高級(jí)程序員的視角是知

3、道刪除的文件,并發(fā)出刪除命令。這些通過(guò)api實(shí)現(xiàn)。 匯編程員的視角是得到要?jiǎng)h除的文件名,找到該文件所在位置,通過(guò)調(diào)用刪除“中斷命令”進(jìn)行刪除。 操作系統(tǒng)開(kāi)發(fā)人員的視角則是接到刪除命令后,先找到系統(tǒng)根目錄區(qū),由根目錄區(qū)的鏈接依次找到子目錄區(qū),直到找到要?jiǎng)h除的文件,然后按照操作系統(tǒng)刪除文件的規(guī)則對(duì)該文件名進(jìn)行修改。比如dos,只把第一個(gè)字符改成?。 按程序語(yǔ)句等價(jià)的角度看,一行vb的打印語(yǔ)句,用匯編實(shí)現(xiàn)大約需要一百二十多行。知道匯編語(yǔ)言的視角后就要知道,前面的道路是坎坷的,沒(méi)有耐心是不行的。想通過(guò)幾分鐘幾行程序就完成很復(fù)雜的操作不是件容易的事。 3、學(xué)匯編有什么用? 匯編產(chǎn)生于dos時(shí)代或更早,而

4、現(xiàn)在是windows時(shí)代,所以可能 遺憾地說(shuō):盡管還有批牛人在用匯編開(kāi)發(fā)核心級(jí)程序,但我們幾乎沒(méi)什么用,除了必要時(shí)間能拿來(lái)分析一兩個(gè)程序的部分代碼之外,別的也就沒(méi)干什么用了。并且并不是所有的匯編命令都能在windows下使用。而泛泛地追求“時(shí)髦”而學(xué)本語(yǔ)言,最后的結(jié)果是損了夫人又折兵。所以學(xué)之前你要考慮好。我勸那些為了當(dāng)“黑客”而學(xué)匯編的人就此止步。第零講 預(yù)備知識(shí) 1、一個(gè)匯編程序的編譯過(guò)程是怎么樣的? 1)首先你需要找一個(gè)編輯器,編輯器用任何“純文本”編輯器都可以。比如記事本。編好以后保存到匯編目錄中。擴(kuò)展名為asm,比如myfirst.asm。但這里建議你找一個(gè)能顯示出當(dāng)前行的編譯器。這

5、樣出錯(cuò)后排錯(cuò)很容易。 2)然后在dos下進(jìn)入d:masm目錄中,輸入“masm myfirst.asm,如果有錯(cuò)系統(tǒng)會(huì)提示出錯(cuò)的行位置和出錯(cuò)原因。 3)然后再輸入“l(fā)ink myfirst.obj”,即可看到當(dāng)前目錄下有一個(gè)myfirst.exe程序。 2、宏匯編和匯編有什么區(qū)別嗎? 二者的區(qū)別在于前者提供宏,后者不提供。后者已找不到了,所以你可以認(rèn)為二者沒(méi)有區(qū)別。 3、機(jī)器語(yǔ)言、匯編語(yǔ)言、高級(jí)語(yǔ)言的關(guān)系 最早的計(jì)算機(jī)采用機(jī)器語(yǔ)言,這種語(yǔ)言直接用二進(jìn)制數(shù)表示,通過(guò)直接輸入二進(jìn)制數(shù),插拔電路板等實(shí)現(xiàn),這種“編程”很容易出錯(cuò),每個(gè)命令都是通過(guò)查命令表實(shí)現(xiàn),既然是通過(guò)“查表”實(shí)現(xiàn)的,那當(dāng)然也可以讓計(jì)

6、算機(jī)來(lái)代替人查表實(shí)現(xiàn)了。于是就產(chǎn)生了匯編語(yǔ)言,所以不管別人怎么定義機(jī)、匯語(yǔ)言,我就認(rèn)為,二者是等價(jià)。后來(lái)人們發(fā)現(xiàn),用匯編語(yǔ)言編某一功能的時(shí)候,連續(xù)一段代碼都是相同或相似,于是就考慮用一句語(yǔ)言來(lái)代替這一段匯編語(yǔ)言,于是就產(chǎn)生了高級(jí)語(yǔ)言。因此,所有高級(jí)語(yǔ)言都能轉(zhuǎn)化成匯編語(yǔ)言,而所以匯編語(yǔ)言又可轉(zhuǎn)化成機(jī)器語(yǔ)言。反之,所有機(jī)器語(yǔ)言可以轉(zhuǎn)成匯編語(yǔ)言(因?yàn)槎叩葍r(jià))。但并不是所以匯編語(yǔ)言都能轉(zhuǎn)成高級(jí)語(yǔ)言。 4、計(jì)算機(jī)的組成 通常都把計(jì)算機(jī)定義成五部分:運(yùn)算器、控制器、存儲(chǔ)器、輸入系統(tǒng)、輸出系統(tǒng)。 為了簡(jiǎn)單起見(jiàn),我們?nèi)绱死斫猓哼\(yùn)算器+控制器=cpu。存儲(chǔ)器=內(nèi)存(暫不包括外存,也不包括cache)。輸入系統(tǒng)

7、=鍵盤(pán)(不包括鼠標(biāo)),輸出系統(tǒng)=顯示器(不包括打印機(jī),繪圖儀)。 5、寄存器和內(nèi)存的區(qū)別 寄存器在cpu中。內(nèi)存在內(nèi)存條中。前者的速度比后者快100倍左右。后面的程序要求每條指定要么沒(méi)有內(nèi)存數(shù)據(jù),要么在有一個(gè)寄存器的參與下有一個(gè)內(nèi)存數(shù)據(jù)。(也就是說(shuō),不存在只訪問(wèn)內(nèi)存的指令)。 6、匯編語(yǔ)言的計(jì)數(shù) 與生活中的計(jì)數(shù)不一樣,匯編中的計(jì)數(shù)是從0開(kāi)始的。比如16個(gè)計(jì)數(shù),則是從015,而不是生活中的116。這一點(diǎn)看起來(lái)簡(jiǎn)單,真運(yùn)算起來(lái)就不是件容易的事了,不信等著瞧。 7、進(jìn)制問(wèn)題 又與生活中不一樣的地方是進(jìn)制。切記下面的常識(shí): *)計(jì)算機(jī)內(nèi)部存儲(chǔ)都用二進(jìn)制。 *)我們的匯編源程序默認(rèn)都用十進(jìn)制。(除非你指

8、明類型) *)我們用的調(diào)試程序debug默認(rèn)的都是十六進(jìn)制。(無(wú)法指明其他類型) 其中十六進(jìn)制的十六個(gè)個(gè)位數(shù)依次是:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f。 8、進(jìn)制轉(zhuǎn)換 一個(gè)比較簡(jiǎn)單的方法是查表法。 十進(jìn)制十六進(jìn)制二進(jìn)制 0 0 0000 1 1 0001 2 2 0010 3 3 0011 4 4 0100 5 5 0101 6 6 0110 7 7 0111 8 8 1000 9 9 1001 10a 1010 11b 1011 12c 1100 13d 1101 14e 1110 15f 1111 好了,結(jié)合6,7,8三條。大家來(lái)算一個(gè)“題”。某一組數(shù)據(jù)顯示時(shí),

9、每個(gè)數(shù)據(jù)占了四個(gè)位置,每行共十六個(gè)。問(wèn):十六進(jìn)制的13位置在哪里(第幾行,第幾列)。 格式如下:m m m m n n n n o o o o p p p p 注:之所以沒(méi)用abc是怕與上面十六進(jìn)制弄混。 r r r r s s s s t t t t u u u u第一講 基礎(chǔ)知識(shí) 1、訪問(wèn)內(nèi)存 程序在內(nèi)存中,訪問(wèn)內(nèi)存是幾乎每一程序都要進(jìn)行的操作,計(jì)算機(jī)對(duì)內(nèi)存編址是線性的,也就是說(shuō)是一維的,比如256m的內(nèi)存,地址就應(yīng)該是從0(256m-1),這個(gè)地址稱為物理地址或絕對(duì)地址。 1.1 地址表示 但從匯編程序員的角度看,內(nèi)存卻是二維的,要說(shuō)明一個(gè)地址,需要給出兩個(gè)值,就象你在平面上指定一點(diǎn)需要

10、說(shuō)出(x,y)坐標(biāo)一樣,匯編程序員的內(nèi)存視角也需要兩個(gè)“坐標(biāo)”,前一個(gè)稱為段地址(segment),后一個(gè)稱為偏移地址(offset),該地址稱為邏輯地址。 比如“1234:3df5”就是一個(gè)地址?!?f3f:”不是一個(gè)地址,因?yàn)樗挥卸蔚刂罚瑳](méi)有偏移地址。注意此后的地址都用十六進(jìn)制表示。 1.2 地址計(jì)算 前面提到,計(jì)算機(jī)編址是一維的,匯編程序員是二維的,那么二者怎么換算呢?由后者到前者的換算方法是,“段地址串”后面加個(gè)“0”,然后再加上偏移地址。 比如“1234:3df5”(十六進(jìn)制的加減運(yùn)算參見(jiàn)相關(guān)資料) 12340 -串后加了一個(gè)0 3df5 - 16135-注意此串仍然是十六進(jìn)制。

11、所以,匯編程序員眼中的地址“1234:3df5”就是物理地址(計(jì)算機(jī)編址):16135。 知道了由后者向前者的轉(zhuǎn)換,那么由前者向后者的轉(zhuǎn)換呢? “不知道”,為什么不知道,繼續(xù)往下看。 1.3 到底哪個(gè)地址對(duì) 知道了1.2的地址算法后,我又發(fā)現(xiàn)一個(gè)問(wèn)題: “1000:6135”的物理地址是多少呢? 10000+6135=16135。 “1001:6125”的物理地址呢? 10010+6125=16135。 . 那么到底哪個(gè)對(duì)呢?問(wèn)題的回答是這樣的:假設(shè)我現(xiàn)在讓你按一下“l(fā)”鍵,我可以告訴你如下幾種方法中的一種或幾種。1 請(qǐng)按一下“l(fā)”鍵; 2請(qǐng)按一下鍵盤(pán)上第四行第十個(gè)鍵;3 請(qǐng)按一下第十列中的第

12、四個(gè)鍵;4 請(qǐng)按一下“k”右邊的鍵;5 按標(biāo)準(zhǔn)指法單擊一下右手無(wú)名指。 舉上面的例子也就是說(shuō),同一個(gè)地址有很多種表示方式,具體用哪一種,要看實(shí)際使用時(shí)的情況。但無(wú)論用哪種方式,只要能達(dá)到目的即可。(實(shí)際中該問(wèn)題一般不會(huì)受此問(wèn)題困擾,但初學(xué)時(shí)突然想不通)。 1.4 有多少內(nèi)存可以訪問(wèn) 無(wú)論是段地址還是偏移地址都是四位十六進(jìn)制(如果不夠四位,前面補(bǔ)0)。也就是說(shuō):總共可以訪問(wèn)的地址說(shuō)是:0000:0000ffff:ffff。 總共ffff0+ffff+1=10fff0個(gè)地址。也就是不到1m的空間。 記住如下結(jié)論: *) 不管你實(shí)際內(nèi)存有多少,目前我們只能訪問(wèn)不到1m的空間。 *) 而實(shí)際上連這1m

13、也用不完。其中上端的384k的址只能讀不能寫(xiě),只能讀,一般稱為rom。 *) 低端的640k可以讀寫(xiě)。但這640k的低端100多k也不能隨便寫(xiě),因此dos系統(tǒng)使用該區(qū)。 *) 原來(lái)1024m的內(nèi)存,匯編程序只能使用其中400多k。這段內(nèi)存的容易相當(dāng)于一個(gè)普通文檔的大小。不過(guò)這就足夠了。 2、debug的使用 先記住以下兩個(gè)命令:d命令和q命令。前者是顯示內(nèi)存內(nèi)容,后者是退出debug命令。 -以下為抄別的人內(nèi)容- debug.exe程序是專門為分析、研制和開(kāi)發(fā)匯編語(yǔ)言程序而設(shè)計(jì)的一種調(diào)試工具,具有跟蹤程序執(zhí)行、觀察中間運(yùn)行結(jié)果、顯示和修改寄存器或存儲(chǔ)單元內(nèi)容等多種功能。它能使程序設(shè)計(jì)人員或用戶

14、觸及到機(jī)器內(nèi)部,因此可以說(shuō)它是80x86cpu的心靈窗口,也是我們學(xué)習(xí)匯編語(yǔ)言必須掌握的調(diào)試工具。 1) debug程序使用 在dos提示符下鍵入命令: cdebug 盤(pán)符:路徑文件名.exe參數(shù)1參數(shù)2 這時(shí)屏幕上出現(xiàn)debug的提示符“-”,表示系統(tǒng)在debug管理之下,此時(shí)可以用debug進(jìn)行程序調(diào)試。若所有選項(xiàng)省略,僅把debug裝入內(nèi)存,可對(duì)當(dāng)前內(nèi)存中的內(nèi)容進(jìn)行調(diào)試,或者再用n和l命令,從指定盤(pán)上裝入要調(diào)試的程序;若命令行中有文件名,則dos把debug程序調(diào)入內(nèi)存后,再由debug將指定的文件名裝入內(nèi)存。 2) debug的常用命令 (1)退出命令 q 格式:q 功能:退出debu

15、g,返回到操作系統(tǒng)。(2)顯示存儲(chǔ)單元命令 d 格式1:d起始地址 格式2:d起始地址結(jié)束地址|字節(jié)數(shù) 功能:格式1從起始地址開(kāi)始按十六進(jìn)制顯示80h個(gè)單元的內(nèi)容,每行16個(gè)單元,共8行,每行右邊顯示16個(gè)單元的ascii碼,不可顯示的ascii碼則顯示“.”。格式2顯示指定范圍內(nèi)存儲(chǔ)單元的內(nèi)容,其他顯示方式與格式1一樣。如果缺省起始地址或地址范圍,則從當(dāng)前的地址開(kāi)始按格式1顯示。 例如:-d 200-表示從ds:0200h開(kāi)始顯示128個(gè)單元內(nèi)容-d 100 120-表示顯示ds:0100-ds:0120單元的內(nèi)容 說(shuō)明:在debug中,地址表示方式有如下形式: 段寄存器名:相對(duì)地址,如:d

16、s:100 段基值:偏移地址(相對(duì)地址),如:23a0:1500 -小抄結(jié)束- 3、驗(yàn)證第一節(jié)里的內(nèi)容 運(yùn)行“開(kāi)始/程序/附件/ms-dos命令提示符”(這是win2000,win98下自己找吧) 在“-”下輸入d,顯示-d1398:0100 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0110 00 00 00 00 00 00 00 00-00 00 00 00 34 00 87 13 .4.1398:0120 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0130

17、 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0140 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0160 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0170 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .- 我們記下:1398:01

18、1c的值是個(gè)34。1389:011c的物理地址應(yīng)該是:13a9c。 那么1000:3a9c的物理地址也應(yīng)該是13a9c,他的內(nèi)存也應(yīng)該是34,(因?yàn)楸緛?lái)就是一個(gè)地址嗎,就象第三行第十列和第十列第三行當(dāng)然應(yīng)該是同一個(gè)位置)。-d 1000:3a9c1000:3a90 34 00 87 13 4.1000:3aa0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1000:3ab0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1000:3ac0 00 00 00 00 00 00 00 00-0

19、0 00 00 00 00 00 00 00 .1000:3ad0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1000:3ae0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1000:3af0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1000:3b00 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1000:3b10 00 00 00 00 00 00 00 00-00 00

20、00 00 .- 果然如此,同樣你可以驗(yàn)證:13a9:000c也肯定是指這一個(gè)地址,不信試試。4、debug命令 -繼續(xù)小抄- 前面已學(xué)過(guò):顯示存儲(chǔ)單元命令 d 再學(xué)一個(gè)命令(1)修改存儲(chǔ)單元命令 e 格式1:e起始地址 內(nèi)容表 格式2:e地址 功能:格式1按內(nèi)容表的內(nèi)容修改從起始地址開(kāi)始的多個(gè)存儲(chǔ)單元內(nèi)容,即用內(nèi)容表指定的內(nèi)容來(lái)代替存儲(chǔ)單元當(dāng)前內(nèi)容。 例如:-e ds:0100 var 12 34 表示從ds:0100 為起始單元的連續(xù)五個(gè)字節(jié)單元內(nèi)容依次被修改為 v、a、r、12h、34h。 格式2是逐個(gè)修改指定地址單元的當(dāng)前內(nèi)容。 如:-e ds:0010 156f:0010 41.5f

21、 其中156f:0010單元原來(lái)的值是41h,5fh為輸入的修改值。若只修改一個(gè)單元的內(nèi)容,這時(shí)按回車鍵即可;若還想繼續(xù)修改下一個(gè)單元內(nèi)容,此時(shí)應(yīng)按空格鍵,就顯示下一個(gè)單元的內(nèi)容,需修改就鍵入新的內(nèi)容,不修改再按空格跳過(guò),如此重復(fù)直到修改完畢,按回車鍵返回debug“-”提示符。如果在修改過(guò)程中,將空格鍵換成按“-”鍵,則表示可以修改前一個(gè)單元的內(nèi)容。 -小抄結(jié)束- 5、使用dos時(shí),匯編用戶可以從dos操作系統(tǒng)中得到什么? 現(xiàn)在編程,通常很多功能都是通過(guò)調(diào)用系統(tǒng)api。很多高級(jí)語(yǔ)言都直接把這些api包裝起來(lái),以系統(tǒng)接口或函數(shù)的方式提供給用戶,那么匯編函數(shù)都能得到什么呢? 首先,匯編用戶有很多

22、東西可以調(diào)用。他們主要是: 5.1 bios提供的接口?,F(xiàn)在硬件與軟件的區(qū)分已越來(lái)越不明顯,很多硬件不僅僅是電路,而還要提供一些固化寫(xiě)入硬件的一部分“程序”,這些程序以rom的方式出現(xiàn),匯編用戶最大的好處就是可以直接使用這些“程序”,這些使用不僅功能強(qiáng)大,而且效率非常高。 5.2 dos功能調(diào)用,作為操作系統(tǒng)也象bios一樣向用戶提供了相應(yīng)的“程序”。這些程序在很大程序上擴(kuò)充了bios。與bios不同的是,這部分程序放在內(nèi)存中,它可以被修改。而bios中不能再修改。 = 以上兩種接口都通過(guò)一種相同的格式調(diào)用,這些程序統(tǒng)稱為“中斷”,現(xiàn)在先不要理解中斷的本意,你現(xiàn)在可以認(rèn)為是系統(tǒng)提供給你的函數(shù)。

23、 = 5.3 系統(tǒng)共享數(shù)據(jù)區(qū)。編過(guò)程序的人都知道全局變量的好處,全局變量方便之外在于任何函數(shù)、過(guò)程都可以調(diào)用、讀取、修改。全局變量不足之處是危險(xiǎn)性,有一個(gè)過(guò)程改了這個(gè)變量值,其它的也得跟著改變了。dos操作系統(tǒng)同樣也提供了這樣的共享數(shù)據(jù)區(qū),該區(qū)是整個(gè)系統(tǒng)的共享區(qū),任何程序都可以查找、修改。當(dāng)然,修改某處必然會(huì)對(duì)其它程序造成影響。 6、再談中斷 前面5.2已提到中斷了,現(xiàn)在問(wèn)題是不同硬件不一樣,即使相同硬件的rom,不同版本,各個(gè)bios中斷程序所處的位置也不一樣。dos中斷也一樣,不同版本、不同配置,在內(nèi)存位置也不一樣。那么你使用某一個(gè)中斷,系統(tǒng)怎么知道你使用的那個(gè)中斷程序在哪呢? 為了解決這

24、一問(wèn)題,dos會(huì)在啟動(dòng)的時(shí)候,把所有這些(bios和dos)中斷的首地址保存到一個(gè)地址。這個(gè)地址很容易記,這段地址是內(nèi)存的絕對(duì)零地址(0000:0000)。前面已講過(guò),每個(gè)地址在匯編程序員角度來(lái)看是二維的,也就是分為段地址和偏移地址。每個(gè)地址各占兩個(gè)字節(jié),所以要表示這個(gè)二維地址需要4個(gè)字節(jié)。所以每個(gè)中斷首地址由4個(gè)字節(jié)表示。一共256個(gè)中斷,占用了1024個(gè)字節(jié)的位置。 另外需要注意的是,這4個(gè)表示地址的字節(jié),數(shù)據(jù)是由低向高的。比如12 34 56 78所表示的地址是:7856:3412。 一般用int m表示中斷m,如果m是十六進(jìn)制,則在后面加上一個(gè)h。比如19號(hào)中斷,十六進(jìn)制應(yīng)該是13h。

25、所以該中斷就是int 13h。 7、再談系統(tǒng)共享數(shù)據(jù)區(qū) 該共享數(shù)據(jù)區(qū)在絕對(duì)地址:0040:0000開(kāi)始。 8、驗(yàn)證我上面說(shuō)的內(nèi)容 8.1 找中斷 運(yùn)行debug后。輸入d 0000:0000。顯示絕對(duì)零地址的內(nèi)容。c:debug-d 0:00000:0000 68 10 a7 00 8b 01 70 00-16 00 9b 03 8b 01 70 00 h.p.p.0000:0010 8b 01 70 00 b9 06 0e 02-40 07 0e 02 ff 03 0e 02 .p.0000:0020 46 07 0e 02 0a 04 0e 02-3a 00 9b 03 54 00 9b

26、03 f.:.t.0000:0030 6e 00 9b 03 88 00 9b 03-a2 00 9b 03 ff 03 0e 02 n.0000:0040 a9 08 0e 02 99 09 0e 02-9f 09 0e 02 5d 04 0e 02 .0000:0050 a5 09 0e 02 0d 02 dc 02-b8 09 0e 02 8b 05 0e 02 .0000:0060 02 0c 0e 02 08 0c 0e 02-13 0c 0e 02 ad 06 0e 02 .0000:0070 ad 06 0e 02 a4 f0 00 f0-37 05 0e 02 71 84 00

27、 c0 .7.q.-u 0070:018b0070:018b 1e push ds0070:018c 50 push ax0070:018d b84000 movax,00400070:0190 8ed8 movds,ax0070:0192 f70614030024 test word ptr 0314,24000070:0198 754f jnz01e90070:019a 55 push bp0070:019b 8bec movbp,sp0070:019d 8b460a movax,bp+0a0070:01a0 5d popbp0070:01a1 a90001 test ax,0100007

28、0:01a4 7543 jnz01e90070:01a6 a90002 test ax,02000070:01a9 7422 jz 01cd 首先,d命令把中斷首地址顯示出來(lái)。每4個(gè)表示一個(gè)地址。其中int 0的中斷首地址為:00a7:1068,int 1的中斷地址為:0070:018b.0070:018b是中斷3的首地址。后面那個(gè)u命令就表示顯示該地址的“中斷程序”的內(nèi)存。 你們可以試著找找int 13h的位置在哪。 8.2 驗(yàn)證系統(tǒng)共享數(shù)據(jù)區(qū) 系統(tǒng)共享數(shù)據(jù)區(qū)內(nèi)容極為豐富,我實(shí)在記不住哪么多了。我曾記在一個(gè)本上,可惜那個(gè)本早在n年前(3ndebug-d 40:00040:0000 f8 03

29、 f8 02 e8 03 e8 02-bc 03 78 03 78 02 80 9f .x.x.0040:0010 22 c8 00 80 02 28 00 00-00 00 2a 00 2a 00 20 39 .(.*.*. 90040:0020 34 05 30 0b 3a 27 30 0b-0d 1c 64 20 20 39 34 05 4.0.:0.d 94.0040:0030 30 0b 3a 27 30 0b 0d 1c-71 10 0d 1c 64 20 00 00 0.:0.q.d .0040:0040 a2 00 c3 00 a2 af 09 e1-c8 03 50 00 0

30、0 10 00 00 .p.0040:0050 00 18 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .0040:0060 0f 0c 00 d4 03 29 30 7f-03 00 c0 00 a1 b7 11 00 .)0.0040:0070 00 00 00 00 00 00 00 00-14 14 14 00 01 01 01 01 .-d 0040:00000040:0000 f8 03 f8 02 e8 03 e8 02-bc 03 78 03 78 02 80 9f .x.x.0040:0010 22 c8 00 80 02 28 00

31、00-00 00 2a 00 2a 00 3a 27 .(.*.*.:0040:0020 30 0b 30 0b 30 0b 30 0b-0d 1c 64 20 20 39 30 0b .d 90.0040:0030 30 0b 30 0b 30 0b 08 0e-08 0e 34 05 30 0b 00 00 .0.0040:0040 1f 00 c3 00 a2 af 09 e1-c8 03 50 00 00 10 00 00 .p.0040:0050 00 18 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .0040:0

32、060 0f 0c 00 d4 03 29 30 7f-03 00 c0 00 24 b8 11 00 .)0.$.0040:0070 00 00 00 00 00 00 00 00-14 14 14 00 01 01 01 01 .- 既然是鍵盤(pán)緩沖區(qū),每個(gè)輸入的鍵都會(huì)顯示在該區(qū)中,第一次我只輸入了“d 40:0”,所以你可以在此后顯示數(shù)據(jù)右邊字符中找到這些字符,注意是間隔開(kāi)的。 第二次我輸入“d 0040:0000”,則右邊顯示的是“d 0040:0000”的內(nèi)容。你可以找找。 第二講 內(nèi)存映象 之所以把這個(gè)內(nèi)存單獨(dú)放一章,是為了說(shuō)明它的重要性,后面的幾乎很多程序都需要你對(duì)這一章的理解。這

33、里的內(nèi)存映象就是指當(dāng)你把一個(gè)可執(zhí)行文件(exe或com文件)放到內(nèi)存后,整個(gè)內(nèi)存“看”起來(lái)是什么樣子的。 前面講過(guò),這里匯編程序只能訪問(wèn)1m的內(nèi)存空間,所以下面就以1m內(nèi)存為例。并且以dos操作系統(tǒng)作為講解對(duì)象,所以所編出來(lái)的程序也僅是dos程序。事實(shí)上,通過(guò)winasm可以訪問(wèn)遠(yuǎn)遠(yuǎn)超過(guò)1m的空間,并且可以編出for windows的程序。但那是另外的話題。我們暫且不說(shuō)那些。 2.1內(nèi)存映象 首先,這1m內(nèi)存如果我們不再以二維的方式看,而是一維的,線性地看(二維和一維的轉(zhuǎn)化方式參見(jiàn)前面章節(jié))。但描述還是以二維的方式描述,從最底端到最高端依次是: 1) 中斷向量區(qū):該區(qū)由0000:0000000

34、0:03ff。這里存著系統(tǒng)的所有中斷的中斷向量表。對(duì)于中斷向量表,你現(xiàn)在先理解為一些程序的首地址。由這個(gè)地址你就能找到該程序。 2) 系統(tǒng)數(shù)據(jù)區(qū):該區(qū)由0040:00000040:xxxx (不好意思,忘了),這里存著整個(gè)系統(tǒng)中,dos操作系統(tǒng)要用的數(shù)據(jù),由于這個(gè)區(qū)的數(shù)據(jù)對(duì)用戶是開(kāi)放的,所以用戶當(dāng)然也可以從這里讀出來(lái)用。 3) dos操作系統(tǒng)區(qū):操作系統(tǒng)常駐內(nèi)存,你向計(jì)算機(jī)發(fā)的每個(gè)命令其實(shí)都是操作系統(tǒng)執(zhí)行的。這個(gè)區(qū)的大小主要是由操作系統(tǒng)的版本和用戶的配置大小決定,如果是驅(qū)動(dòng)程序配置,就放到根目錄下的config.sys里,如果是程序,就放到autoexec.bat里。這里設(shè)置在現(xiàn)在的windo

35、ws 95/98/nt/me/2000/xp/2003中仍然有,所以我就不多說(shuō)了。 4) 用戶程序:這個(gè)當(dāng)然就是你執(zhí)行的程序了,這種程序分兩種,一種是擴(kuò)展名為com文件,一種是exe文件。從程序內(nèi)部看,前者程序的四個(gè)段重合(后面要講這四個(gè)段),所以最大長(zhǎng)度只等于一個(gè)段,用前面段地址的理解就是com文件最大只能是64k,所以com文件只適合小的程序。而exe,四個(gè)段可任何分配,并可擴(kuò)充段,而且每個(gè)段的段地址可以任何改動(dòng),因此exe的訪問(wèn)內(nèi)存能力大多了。這種格式訪問(wèn)能力只受地址結(jié)構(gòu)的限制了。 用戶程序所占的內(nèi)存大小完全由程序本身決定,但最大,只能到640k。這一點(diǎn),怪不得別人,只能怪當(dāng)前計(jì)算機(jī)軟硬

36、件設(shè)置高手高手高高手們(包括比爾蓋茨)們的失誤了,60年代的超級(jí)計(jì)算機(jī)只有36k的內(nèi)存,所以他們就在80年代得到一個(gè)結(jié)論:640k的內(nèi)存足夠了。 如果用戶程序大于由操作系統(tǒng)所占內(nèi)存的頂?shù)椎?40k之間的內(nèi)存量,就會(huì)顯示:內(nèi)存不夠,因而程序不能執(zhí)行。這種現(xiàn)象對(duì)于一開(kāi)始就用windows的人來(lái)說(shuō),幾乎沒(méi)見(jiàn)過(guò),但對(duì)于一開(kāi)始用dos并打漢字的人來(lái)說(shuō),再正常不過(guò)。如果小于這段內(nèi)存,多余部分就空著。 5) 從640k到1m-64k,這段內(nèi)存就很難說(shuō)清了。這段內(nèi)存中有一部分被硬件占有,有一部分是顯示緩沖區(qū)點(diǎn)有,還有一部分是系統(tǒng)rom占有。 6) 從1m-64k到1m之間的這段64k的內(nèi)存叫作hma。這段內(nèi)存

37、是小孩沒(méi)娘,說(shuō)來(lái)話長(zhǎng),我們先不說(shuō)他。 2.2 驗(yàn)證上面的理論 2.2.1 中斷向量表 中斷向量表就是所有中斷向量首地址表,這里保存著每個(gè)中斷程序的首地址,幾乎所有的匯編書(shū)都把中斷放到后面的章節(jié)中,并且對(duì)中斷的解釋也僅從字面意思解釋,所以導(dǎo)致大學(xué)對(duì)中斷的不重要和誤解。沒(méi)耐心的沒(méi)到這個(gè)章節(jié)就不學(xué)匯編了,有耐心的到這里才豁然開(kāi)朗。我現(xiàn)在不講中斷的原意。我直接告訴你,你把中斷當(dāng)成api也許更合適。也就是說(shuō),別人把很多已作好的功能放到了內(nèi)存中。并且把調(diào)用這一功能的號(hào)告訴了你,你只要調(diào)用這些功能號(hào),系統(tǒng)就自動(dòng)從這個(gè)中斷向量表中找到對(duì)應(yīng)的中斷,然后執(zhí)行你的功能。 首先讓你感受一下中斷的魅力一下吧。比如中斷2

38、1h的2a功能調(diào)用是讀取系統(tǒng)的日期,這個(gè)調(diào)用的規(guī)則是,調(diào)用前ah寄存器置為2a。調(diào)用后年在cx中,月在dh中,dl在日中,星期在al中。-a139d:0100 mov ah,2a139d:0102 int 21139d:0104 int 3139d:0105-g=100 ax=2a05 bx=0000 cx=07d4 dx=0c18 sp=ffee bp=0000 si=0000 di=0000ds=139d es=139d ss=139d cs=139d ip=0104 nv up ei pl nz na po nc139d:0104 cc int 3- 可能上面的程序你目前還看不懂。不過(guò)沒(méi)

39、關(guān)系,“mov ah,2a”表示調(diào)用功能號(hào)是2a的api?!癷nt 21”表示調(diào)用十六進(jìn)制21號(hào)中斷,“int 3”表示3號(hào)中斷,表示程序運(yùn)行到這一句時(shí)停一下。“g=100”表示從“139d:0100 ”開(kāi)始執(zhí)行。 ax=2a05 bx=0000 cx=07d4 dx=0c18 sp=ffee bp=0000 si=0000 di=0000 ds=139d es=139d ss=139d cs=139d ip=0104 nv up ei pl nz na po nc 表示執(zhí)行的結(jié)果。其中cx是年,這個(gè)年是由cx中存。07d4十進(jìn)制就是2004年。dh+dl=dx,所以dh=0c,dl=18。二

40、者轉(zhuǎn)化為十進(jìn)制就是dh=12,dl=24,也就是今天了。ax=ah+al=2a05,所以al=05。那就是今天是星期五。 上面可能你們現(xiàn)在還看不懂,不過(guò)通過(guò)解說(shuō)你應(yīng)該可以知道,僅僅兩行命令,就讀到了現(xiàn)在的值?,F(xiàn)在需要作的就是把這些值提取出來(lái)用作他用了。 從中斷的作來(lái)與中斷向量表又有什么關(guān)系呢?原來(lái)你在匯編里運(yùn)行int 21時(shí),系統(tǒng)就在上面的中斷向量表中找到int 21的中斷地址,該中斷的地址應(yīng)該位于: 0000:00840000:0087,具體算法前面已說(shuō)明了。-d 0000:0084 00870000:0080 7c 10 a7 00 |.- 找到內(nèi)容是:00a7:107c。然后系統(tǒng)就轉(zhuǎn)到這

41、個(gè)地址執(zhí)行int 21。 2.2.2 系統(tǒng)數(shù)據(jù)區(qū) 前面都已說(shuō)明過(guò)。不再多說(shuō)。系統(tǒng)區(qū),很多dos中斷程序?qū)崿F(xiàn)部分就在這個(gè)區(qū)。程序運(yùn)行區(qū)依不同的程序而不用。 2.2.3 640k1m之間 這期間有些地方是rom,有些地方是硬件的bios區(qū)。我僅以兩個(gè)例子說(shuō)明這一區(qū)。 rom區(qū) :rom區(qū)就是只讀內(nèi)存,也就是說(shuō)這個(gè)區(qū)的數(shù)據(jù)只能讀不能寫(xiě)。比如f000:0000開(kāi)始的內(nèi)存是rom。我們來(lái)寫(xiě)一下,然后再看看效果。 -d f000:0000 0005-顯示由f000:0000到f000:0005的六個(gè)字節(jié)值f000:0000 04 e8 a2 ff f9 c3 .-e f000:0000-修改命令f000:

42、0000 04.00 e8.00 a2.00 ff.00 f9.00 c3.00 -注意,.后面的是我改的,把這幾個(gè)值都改成0了。 -d f000:0000 0005 -再次顯示這個(gè)區(qū)的數(shù)據(jù)。f000:0000 04 e8 a2 ff f9 c3 .- 通過(guò)上面測(cè)試,發(fā)現(xiàn)該區(qū)數(shù)據(jù)仍然未改變。但你要是試別的ram區(qū)的,肯定會(huì)變。如果想試你自己試試吧。 顯示緩沖區(qū) :在文本方式下,b800:0000開(kāi)始的地址保存著屏幕上每個(gè)字符位置的值。在文本方式下,屏幕被分為8025。每個(gè)位置有兩個(gè)值,一個(gè)值是ascii字符,一個(gè)值是該ascii的屬性值(主要是顏色)。所以一個(gè)屏幕共有80252=400個(gè)字符。

43、 我們來(lái)改:-d b800:0000 0010 -顯示屏幕緩沖區(qū)的內(nèi)容,注意此時(shí)本行最左邊的“-”是屏幕左上角。b800:0000 2d 07 64 07 20 07 62 07-38 07 30 07 30 07 3a 07 -.d. .b.8.0.0.:.b800:0010 30 0- 看上面的命令,屏幕最上邊一行是“-d b800:0000 0010”,所以他的內(nèi)容就是“2d 07 64 07 20 07 62 07-38 07 30 07 30 07 3a 07”其中,2d是“-”的ascii值,07是“-”的屬性值。64是“d”的ascii值,07是“d”的屬性值。 現(xiàn)在修改這些值。

44、我把左上角的字改成黃顏色的“-”,那當(dāng)然是改b800:0001的屬性值了。-e b800:0001 0e 是不是左上角的顏色變成黃色了嗎? 好了,把第二個(gè)字符變成綠色的“-”吧?-e b800:0002 2d 0b 變了嗎? 2.3 可執(zhí)行文件內(nèi)存映象 dos下可執(zhí)行文件有兩種(bat是批處理文件,他只是簡(jiǎn)單調(diào)用dos內(nèi)部命令或其它程序,所以此處不認(rèn)為它是可執(zhí)行文件):一種是com文件,一種是exe文件,前面提到,com文件一般小于64k。exe文件則可以任意大。為什么呢? 說(shuō)到這里,還要提到段。每個(gè)段64k。段的作用就是數(shù)據(jù)組織單位。段的類型有三種:代碼段(code segment,簡(jiǎn)稱cs

45、)、數(shù)據(jù)段(data segment,簡(jiǎn)稱ds)、棧段(stack segment,簡(jiǎn)稱ss),另外還有一個(gè)附加數(shù)據(jù)段(extra segment,簡(jiǎn)稱es),它的用與數(shù)據(jù)段ds可以認(rèn)為完全一樣,當(dāng)數(shù)據(jù)段的64k不夠用,或你就需要把數(shù)據(jù)放到兩個(gè)段中以便移動(dòng)、復(fù)制、比較時(shí),才用到附加數(shù)據(jù)段es。(當(dāng)然,移動(dòng)、復(fù)制、比較操作在一個(gè)段中也可以完成)。 1.段的作用 1.1 代碼段(cs):程序裝入內(nèi)存中,dos怎么知道是從哪里執(zhí)行呢?答案就是系統(tǒng)自動(dòng)從代碼段指定位置開(kāi)始執(zhí)行,并且始終在代碼段中執(zhí)行。因此代碼段cs的作用就是保存所有的指令。這里所說(shuō)的代碼也就是匯編指令了。所以編寫(xiě)匯編程序也就主要是編寫(xiě)

46、代碼段中的代碼。 1.2 數(shù)據(jù)段(ds)、附加段(es):顧名思義,數(shù)據(jù)段中存的就是數(shù)據(jù),這些數(shù)據(jù)供代碼段的程序調(diào)用。附加段就是附加數(shù)據(jù)段。作用與數(shù)據(jù)段相同。 1.3 棧段(ss):這個(gè)段非常重要,但實(shí)際上,你在使用中,似乎用不著這個(gè)段,但實(shí)際上,這是黑客編程中最重要的一部分,而且系統(tǒng)會(huì)不停地“偷偷地”使用這個(gè)段,正是這個(gè)偷偷地用,使得系統(tǒng)的很多動(dòng)作被記錄到這個(gè)段中。還有兩點(diǎn),你必須記住:一是如果你使用了這個(gè)棧,比如你把數(shù)據(jù)存到這個(gè)棧中,則必須有相應(yīng)的出棧命令,并且入幾個(gè)數(shù)據(jù),就得出幾個(gè)數(shù)據(jù),多一個(gè)或少一個(gè),你的程序就可能導(dǎo)致死機(jī)或異常;二是你要把握操作時(shí)機(jī),比如你不能在系統(tǒng)使用棧的前后使用棧

47、,比如你在調(diào)用子程序之前入棧,而在子程序中出棧,而在系統(tǒng)調(diào)用子程序時(shí),系統(tǒng)也要使用棧,這種也將導(dǎo)致出錯(cuò)。 棧就是一種先入后出(也有稱為后入先出)的結(jié)構(gòu),有地址由小到大的增加棧,有地址由大到小的逆向減棧。 2.段重疊 從上面,我們可以看到,cs,ds,ss三者作用各不相同,內(nèi)存就是象錄音磁帶,錄新歌,則舊歌被刪,帶子上存的始終是最后錄的那段音樂(lè)。因此,如果重疊則必然相互沖突。那還能重疊嗎? 這里所說(shuō)的重疊不是指內(nèi)容重疊,而是指概念上的重疊,即數(shù)據(jù)相互放到一個(gè)段中,但相互可以區(qū)分開(kāi)。比如某一段既有數(shù)據(jù)也有代碼,則代碼在每要執(zhí)行到數(shù)據(jù)之前加一個(gè)跳轉(zhuǎn)指令跳過(guò)這段代碼。這個(gè)跳轉(zhuǎn)指令要求用戶在編程的時(shí)候加

48、上。 而棧段呢?棧段有自己的特殊性,特殊就在于系統(tǒng)也會(huì)自動(dòng)地使用,而用戶則又在不知道系統(tǒng)在使用的情況下使用。避免這種沖突的方法就是采用逆向的棧段。 3 .com文件內(nèi)存映象 com文件被讀到內(nèi)存中后,該文件的前100h個(gè)字節(jié)被操作系統(tǒng)使用,操作系統(tǒng)使用這256個(gè)字節(jié)保存一些系統(tǒng)要使用的數(shù)據(jù),匯編語(yǔ)言編程者不能在這里存自己的數(shù)據(jù),但在知道這此數(shù)據(jù)的作用后可以使用其中的數(shù)據(jù)。從100h開(kāi)始,就是程序的開(kāi)始了。com文件之所以最大只能有64k,其原因是com文件的四個(gè)段是相互重疊的。也就是說(shuō),cs、ds、ss、es四個(gè)段的地址都指向這個(gè)com文件的100h處。程序代碼、數(shù)據(jù)、棧都在由100h到64k的區(qū)域內(nèi)。如何把三者分開(kāi)呢?棧段采用逆向棧,這個(gè)棧由64k開(kāi)始,隨著數(shù)據(jù)入棧,則地址就減小。

溫馨提示

  • 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)論