




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、學(xué)習(xí)匯編前應(yīng)該知道的知識(shí)第一講 學(xué)習(xí)匯編前你應(yīng)該知道的知識(shí)1、匯編需要什么工具和程序?目前階段,匯編程序僅需要兩個(gè)程序就夠了。 masm.exe,link.exe。前者是匯編程序,后者是鏈接程序。另外,還需要編輯程序edit.exe,驗(yàn)證和調(diào)試程序debug.exe,這兩個(gè)程序由windows本身提供。建議:將以上4個(gè)文件放到一個(gè)目錄中,如可以建一個(gè)“D:Masm”目錄,并建議此后的程序都放這個(gè)目錄,此后稱這個(gè)目錄為匯編目錄。2、學(xué)習(xí)匯編需要有哪些編程方面的知識(shí)。沒有任何編程方面的知識(shí),學(xué)習(xí)此語言等于緣木求魚,所以請放棄學(xué)習(xí)的想法。一般來說至少要知道如下幾點(diǎn): *)程序的運(yùn)行邏輯結(jié)
2、構(gòu)有順序(按語句依次執(zhí)行)、分支結(jié)構(gòu)(IF.THEN.ELSE.),循環(huán)結(jié)構(gòu)(FOR.NEXT)三種結(jié)構(gòu)。 *)知道什么是子程序,什么是調(diào)用。 *)匯編程序員的視角。不同編程視角編程要求是不一樣的。比如刪除文件, >>用戶的視角是找到“刪除”按鈕或菜單,然后單擊一下即可。 >>高級(jí)程序員的視角是知道刪除的文件,并發(fā)出刪除命令。這些通過API實(shí)現(xiàn)。 >>匯編程
3、員的視角是得到要?jiǎng)h除的文件名,找到該文件所在位置,通過調(diào)用刪除“中斷命令”進(jìn)行刪除。 >>操作系統(tǒng)開發(fā)人員的視角則是接到刪除命令后,先找到系統(tǒng)根目錄區(qū),由根目錄區(qū)的鏈接依次找到子目錄區(qū),直到找到要?jiǎng)h除的文件,然后按照操作系統(tǒng)刪除文件的規(guī)則對該文件名進(jìn)行修改。比如DOS,只把第一個(gè)字符改成"?"。 按程序語句等價(jià)的角度看,一行VB的打印語句,用匯編實(shí)現(xiàn)大約需要一百二十多行。知道匯編語言的視角后就要知道,前面的道路是坎坷的,沒有耐心是不行的。想通過幾分鐘幾行程序就完成很復(fù)雜的操作不是件容易的事。
4、3、學(xué)匯編有什么用?² 匯編產(chǎn)生于DOS時(shí)代或更早,而現(xiàn)在是Windows時(shí)代,所以可能遺憾地說:盡管還有批牛人在用匯編開發(fā)核心級(jí)程序,但我們幾乎沒什么用,除了必要時(shí)能拿來分析一兩個(gè)程序的部分代碼之外,別的也就沒什么用了。并且并不是所有的匯編命令都能在windows下使用。而泛泛地追求“時(shí)髦”而學(xué)本語言。這是大錯(cuò)特錯(cuò)的。不要忘記我們是計(jì)算機(jī)專業(yè)學(xué)生!² 勸那些為了當(dāng)“黑客”而學(xué)匯編的人就此止步。第二講 預(yù)備知識(shí)1 一個(gè)匯編程序的編譯過程是怎么樣的。 1)首先你需要找一個(gè)編輯器,編輯器用任何“純文本”編輯器都可以。比如記事本。編好以后保存到匯編目錄中。擴(kuò)展名為as
5、m,比如myfirst.asm。但這里建議你找一個(gè)能顯示出當(dāng)前行的編譯器。這樣出錯(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)為二者沒有區(qū)別。3 機(jī)器語言、匯編語言、高級(jí)語言的關(guān)系 最早的計(jì)算機(jī)采用機(jī)器語言,這種語言直接用二進(jìn)制數(shù)表示,通過
6、直接輸入二進(jìn)制數(shù),插拔電路板等實(shí)現(xiàn),這種“編程”很容易出錯(cuò),每個(gè)命令都是通過查命令表實(shí)現(xiàn),既然是通過“查表”實(shí)現(xiàn)的,那當(dāng)然也可以讓計(jì)算機(jī)來代替人查表實(shí)現(xiàn)了。于是就產(chǎn)生了匯編語言,所以不管別人怎么定義機(jī)、匯語言,我就認(rèn)為,二者是等價(jià)。后來人們發(fā)現(xiàn),用匯編語言編某一功能的時(shí)候,連續(xù)一段代碼都是相同或相似,于是就考慮用一句語言來代替這一段匯編語言,于是就產(chǎn)生了高級(jí)語言。因此,所有高級(jí)語言都能轉(zhuǎn)化成匯編語言,而所以匯編語言又可轉(zhuǎn)化成機(jī)器語言。反之,所有機(jī)器語言可以轉(zhuǎn)成匯編語言(因?yàn)槎叩葍r(jià))。但并不是所以匯編語言都能轉(zhuǎn)成高級(jí)語言。4 計(jì)算機(jī)的組成 通常都把計(jì)算機(jī)定義成五部分:運(yùn)算器、控制器
7、、存儲(chǔ)器、輸入系統(tǒng)、輸出系統(tǒng)。 為了簡單其間,我們?nèi)绱死斫猓哼\(yùn)算器+控制器=CPU。存儲(chǔ)器=內(nèi)存(暫不包括外存,永不包括CACHE)。輸入系統(tǒng)=鍵盤(不包括鼠標(biāo)),輸入系統(tǒng)=顯示器(不包括打印機(jī),繪圖儀)。5 寄存器和內(nèi)存的區(qū)別 寄存器在CPU中。內(nèi)存在內(nèi)存條中。前者的速度比后者快100倍左右。后面的程序要求每條指定要么沒有內(nèi)存數(shù)據(jù),要么在有一個(gè)寄存器的參與下有一個(gè)內(nèi)存數(shù)據(jù)。(也就是說,不存在只訪問內(nèi)存的指令)。6 匯編語言的計(jì)數(shù) 與生活中的計(jì)數(shù)不一樣,匯編中的計(jì)數(shù)是從0開始的。比如16個(gè)計(jì)數(shù),則是從015,而不是生活中的116。這一點(diǎn)看起來簡單,真運(yùn)算起來
8、就不是件容易的事了,不信等著瞧。7 進(jìn)制問題 又與生活中不一樣的地方是進(jìn)制。切記下面的常識(shí): *)計(jì)算機(jī)內(nèi)部存儲(chǔ)都用二進(jìn)制。 *)我們的匯編源程序默認(rèn)都用十進(jìn)制。(除非你指明類型) *)我們用的調(diào)試程序debug默認(rèn)的都是十六進(jìn)制。(無法指明其他類型) 其中十六進(jìn)制的十六個(gè)個(gè)位數(shù)依次是:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F(xiàn)。8 進(jìn)制轉(zhuǎn)換 一個(gè)比較簡單的方法是查表法。 十進(jìn)制 十六進(jìn)制 二進(jìn)制 0
9、0; 0 0000 1 1 0001 2 2 0010 3 &
10、#160; 3 0011 4 4 0100 5 5 0101 6
11、0; 6 0110 7 7 0111 8 8 1000 9 &
12、#160; 9 1001 10 A 1010 11 B 1011 12 C
13、; 1100 13 D 1101 14 E 1110 15 F 1111 好了,結(jié)合6,7,8三條。大家來
14、算一個(gè)“題”。某一組數(shù)據(jù)顯示時(shí),每個(gè)數(shù)據(jù)占了四個(gè)位置,每行共十六個(gè)。問:十六進(jìn)制的13位置在哪里(第幾行,第幾列)。 格式如下:m m m m n n n n o o o o p p p p '注:之所以沒用ABC是怕與上面十六進(jìn)制弄混。 r r r r s s s s t t t t u u u u第一講 基礎(chǔ)知識(shí)1 訪問內(nèi)存 程序在內(nèi)存中,訪問內(nèi)存是幾乎每一程序都要進(jìn)行的操作,計(jì)算機(jī)對內(nèi)存編址是線性的,也就是說是一維的,比如25
15、6M的內(nèi)存,地址就應(yīng)該是從0(256M-1),這個(gè)地址稱為物理地址或絕對地址。1.1 地址表示 但從匯編程序員的角度看,內(nèi)存卻是二維的,要說明一個(gè)地址,需要給出兩個(gè)值,就象你在平面上指定一點(diǎn)需要說出(X,Y)坐標(biāo)一樣,匯編程序員的內(nèi)存視角也需要兩個(gè)“坐標(biāo)”,前一個(gè)稱為段地址(Segment),后一個(gè)稱為偏移地址(Offset),該地址稱為邏輯地址。 比如“1234:3DF5”就是一個(gè)地址?!?F3F:”不是一個(gè)地址,因?yàn)樗挥卸蔚刂?,沒有編移地址。注意此后的地址都用十六進(jìn)制表示。1.2 地址計(jì)算 前面提到,計(jì)算機(jī)編址是一維的,匯編程序員是二維的,那么二者怎么
16、換算呢?由后者到前者的換算方法是,“段地址串”后面加個(gè)“0”,然后再加上偏移地址。 比如“1234:3DF5”(十六進(jìn)制的加減運(yùn)算參見相關(guān)資料)12340 串后加了一個(gè)03DF5-16135 注意此串仍然是十六進(jìn)制。 所以,匯編程序員眼中的地址“1234:3DF5”就是物理地址(計(jì)算機(jī)編址):16135。 知道了由后者向前者的轉(zhuǎn)換,那么由前者向后者的轉(zhuǎn)換呢? “不知道”,為什么不知道,繼續(xù)往下看。1.3 到底哪個(gè)地址對。 知道了1.2的地址算法后,我又
17、發(fā)現(xiàn)一個(gè)問題: “1000:6135”的物理地址是多少呢? 10000+6135=16135。 “1001:6125”的物理地址呢? 10010+6125=16135。 . 那么到底哪個(gè)對呢?問題的回答是這樣的:假設(shè)我現(xiàn)在讓你按一下“L”鍵,我可以告訴你如下幾種方法中的一種或幾種。1 請按一下“L”鍵; 2請按一下鍵盤上第四行第十個(gè)鍵;3 請按一下第十列中的第四個(gè)鍵;4 請按一下“K”右邊的鍵;5 按標(biāo)準(zhǔn)指法單擊一下右手無名指。
18、 舉上面的例子也就是說,同一個(gè)地址有很多種表示方式,具體用哪一種,要看實(shí)際使用時(shí)的情況。但無論用哪種方式,只要能達(dá)到目的即可。(實(shí)際中該問題一般不會(huì)受此問題困擾,但初學(xué)時(shí)突然想不通)。1.4 有多少內(nèi)存可以訪問 無論是段地址還是偏移地址都是四位十六進(jìn)制(如果不夠四位,前面補(bǔ)0)。也就是說:總共可以訪問的地址說是:0000:0000FFFF:FFFF。 總共FFFF0+FFFF+1=10FFF0個(gè)地址。也就是不到1M的空間。 記住如下結(jié)論: *)不管你實(shí)際內(nèi)存有多少,目前我們只能訪問不到1M的空間。 *)而實(shí)際上連這1M也用不完。其中上
19、端的384K的址只能讀不能寫,只能讀,一般稱為ROM。 *)低端的640K可以讀寫。但這640K的低端100多K也不能隨便寫,因此DOS系統(tǒng)使用該區(qū)。 *)原來1024M的內(nèi)存,匯編程序只能使用其中400多K。這段內(nèi)存的容易相當(dāng)于一個(gè)普通文檔的大小。不過這就足夠了。2 DEBUG的使用先記住以下兩個(gè)命令:D命令和Q命令。前者是顯示內(nèi)存內(nèi)容,后者是退出DEBUG命令。-以下為抄別的人內(nèi)容-DEBUG.EXE程序是專門為分析、研制和開發(fā)匯編語言程序而設(shè)計(jì)的一種調(diào)試工具,具有跟蹤程序執(zhí)行、觀察中間運(yùn)行結(jié)果、顯示和修改寄存器或存儲(chǔ)單元內(nèi)容等多種功能。它能使程序設(shè)計(jì)人員或用戶觸及
20、到機(jī)器內(nèi)部,因此可以說它是80X86CPU的心靈窗口,也是我們學(xué)習(xí)匯編語言必須掌握的調(diào)試工具。 1)DEBUG程序使用在DOS提示符下鍵入命令: C>DEBUG 盤符:路徑文件名.EXE參數(shù)1參數(shù)2 這時(shí)屏幕上出現(xiàn)DEBUG的提示符“-”,表示系統(tǒng)在DEBUG管理之下,此時(shí)可以用DEBUG進(jìn)行程序調(diào)試。若所有選項(xiàng)省略,僅把DEBUG裝入內(nèi)存,可對當(dāng)前內(nèi)存中的內(nèi)容進(jìn)行調(diào)試,或者再用N和L命令,從指定盤上裝入要調(diào)試的程序;若命令行中有文件名,則DOS把DEBUG程序調(diào)入內(nèi)存后,再由DEBUG將指定的文件名裝
21、入內(nèi)存。2)DEBUG的常用命令(1)退出命令 Q 格式:Q 功能:退出DEBUG,返回到操作系統(tǒng)。(2)顯示存儲(chǔ)單元命令 D格式1:D起始地址 格式2:D起始地址結(jié)束地址|字節(jié)數(shù) 功能:格式1從起始地址開始按十六進(jìn)制顯示80H個(gè)單元的內(nèi)容,每行16個(gè)單元,共8行,每行右邊顯示16個(gè)單元的ASCII碼,不可顯示的ASCII碼則顯示“·”。格式2顯示指定范圍內(nèi)存儲(chǔ)單元的內(nèi)容,其他顯示方式與格式1一樣。如果缺省起始地址或地址范圍,則從當(dāng)前的地址開
22、始按格式1顯示。例如: -D 200 ;表示從DS:0200H開始顯示128個(gè)單元內(nèi)容 -D 100 120 ;表示顯示DS:0100-DS:0120單元的內(nèi)容 說明:在DEBUG中,地址表示方式有如下形
23、式: 段寄存器名:相對地址,如:DS:100段基值:偏移地址(相對地址),如:23A0:1500-小抄結(jié)束-3 驗(yàn)證第一節(jié)里的內(nèi)容運(yùn)行“開始/程序/附件/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
24、; 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 .1398:0130 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
25、 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:011C的值是個(gè)34。1389:011C的物理地址應(yīng)該是:13A9C。那么1000:3A9C的物理地址也應(yīng)該是13A9C,他的內(nèi)存也應(yīng)該是34,(因?yàn)楸緛砭褪且粋€(gè)地址嗎,就象第三行第十列和第十列第三行當(dāng)然應(yīng)該是同一個(gè)位置)。-d 1000:3A9C1000:3A90
26、160; 34 00 87 13 4.1000:3AA0 00 00 00 00 0
27、0 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-00 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
28、 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 00 00 .-
29、果然如此,同樣你可以驗(yàn)證:13A9:000C也肯定是指這一個(gè)地址,不信試試。4 DEBUG命令-繼續(xù)小抄-前面已學(xué)過:顯示存儲(chǔ)單元命令 D再學(xué)一個(gè)命令(1)修改存儲(chǔ)單元命令 E格式1:E起始地址 內(nèi)容表格式2:E地址功能:格式1按內(nèi)容表的內(nèi)容修改從起始地址開始的多個(gè)存儲(chǔ)單元內(nèi)容,即用內(nèi)容表指定的內(nè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:00
30、10156F:0010 41.5F其中156F:0010單元原來的值是41H,5FH為輸入的修改值。若只修改一個(gè)單元的內(nèi)容,這時(shí)按回車鍵即可;若還想繼續(xù)修改下一個(gè)單元內(nèi)容,此時(shí)應(yīng)按空格鍵,就顯示下一個(gè)單元的內(nèi)容,需修改就鍵入新的內(nèi)容,不修改再按空格跳過,如此重復(fù)直到修改完畢,按回車鍵返回DEBUG“-”提示符。如果在修改過程中,將空格鍵換成按“-”鍵,則表示可以修改前一個(gè)單元的內(nèi)容。-小抄結(jié)束-5 使用DOS時(shí),匯編用戶可以從DOS操作系統(tǒng)中得到什么? 現(xiàn)在編程,通常很多功能都是通過調(diào)用系統(tǒng)API。很多高級(jí)語言都直接把這些API包裝起來,以系統(tǒng)接口或函數(shù)的方式提供給用戶,那么匯編函
31、數(shù)都能得到什么呢? 首先,匯編用戶有很多東西可以調(diào)用。他們主要是: 5.1 BIOS提供的接口?,F(xiàn)在硬件與軟件的區(qū)分已越來越不明顯,很多硬件不僅僅是電路,而還要提供一些固化寫入硬件的一部分“程序”,這些程序以ROM的方式出現(xiàn),匯編用戶最大的好處就是可以直接使用這些“程序”,這些使用不僅功能強(qiáng)大,而且效率非常高。 5.2 DOS功能調(diào)用,作為操作系統(tǒng)也象BIOS一樣向用戶提供了相應(yīng)的“程序”。這些程序在很大程序上擴(kuò)充了BIOS。與BIOS不同的是,這部分程序放在內(nèi)存中,它可以被修改。而BIOS中不能再修改。 = 以上兩種接口都通過一種相
32、同的格式調(diào)用,這些程序統(tǒng)稱為“中斷”,現(xiàn)在先不要理解中斷的本意,你現(xiàn)在可以認(rèn)為是系統(tǒng)提供給你的函數(shù)。 = 5.3 系統(tǒng)共享數(shù)據(jù)區(qū)。編過程序的人都知道全局變量的好處,全局變量方便之外在于任何函數(shù)、過程都可以調(diào)用、讀取、修改。全局變量不足之處是危險(xiǎn)性,有一個(gè)過程改了這個(gè)變量值,其它的也得跟著改變了。DOS操作系統(tǒng)同樣也提供了這樣的共享數(shù)據(jù)區(qū),該區(qū)是整個(gè)系統(tǒng)的共享區(qū),任何程序都可以查找、修改。當(dāng)然,修改某處必然會(huì)對其它程序造成影響。6 再談中斷 前面5.2已提到中斷了,現(xiàn)在問題是不同硬件不一樣,即使相同硬件的ROM,不同版本,各個(gè)BIOS中斷程序所處的位置也不一樣
33、,DOS中斷也一樣,不同版本、不同配置,在內(nèi)存位置也不一樣。那么你使用某一個(gè)中斷,系統(tǒng)怎么知道你使用的那個(gè)中斷程序在哪呢? 為了解決這一問題,DOS會(huì)在啟動(dòng)的時(shí)候,把所有這些(BIOS和DOS)中斷的首地址保存到一個(gè)地址。這個(gè)地址很容易記,這段地址是內(nèi)存的絕對零地址(0000:0000)。前面已講過,每個(gè)地址在匯編程序員角度來看是二維的,也就是分為段地址和偏移地址。每個(gè)地址各占兩個(gè)字節(jié),所以要表示這個(gè)二維地址需要4個(gè)字節(jié)。所以每個(gè)中斷首地址由4個(gè)字節(jié)表示。一共256個(gè)中斷,占用了1024個(gè)字節(jié)的位置。 另外需要注意的是,這4個(gè)表示地址的字節(jié),數(shù)據(jù)是由低向高的。比如12
34、34 56 78所表示的地址是:7856:3412。一般用INT M表示中斷M,如果M是十六進(jìn)制,則在后面加上一個(gè)H。比如19號(hào)中斷,十六進(jìn)制應(yīng)該是13H。所以該中斷就是INT 13H。7 再談系統(tǒng)共享數(shù)據(jù)區(qū) 該共享數(shù)據(jù)區(qū)在絕對地址:0040:0000開始。8 驗(yàn)證我上面說的內(nèi)容 8.1 找中斷 運(yùn)行DEBUG后。輸入D 0000:0000。顯示絕對零地址的內(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
35、.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 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:00
36、50 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 C0 .7.q.-u 0070:018B0070:018B 1E
37、 PUSH DS0070:018C 50 PUSH AX0070:018D B84000 MOV AX,00400070:0190 8ED8 MOV
38、0; DS,AX0070:0192 F70614030024 TEST WORD PTR 0314,24000070:0198 754F JNZ 01E90070:019A 55 PUSH BP0070:019B 8BEC
39、60; MOV BP,SP0070:019D 8B460A MOV AX,BP+0A0070:01A0 5D POP BP0070:01A1 A90001 &
40、#160; TEST AX,01000070:01A4 7543 JNZ 01E90070:01A6 A90002 TEST AX,02000070:01A9 7422
41、 JZ 01CD首先,D命令把中斷首地址顯示出來。每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年前(3<N&l
42、t;6)就丟了。兄弟們誰找到這個(gè)地址的內(nèi)容,一定要貼上來,這里有東西可以讓大家眼界大開。 前幾年,我用的286計(jì)算機(jī)是黑白顯示器(555555,別嫌我老、舊、慢呀),可當(dāng)時(shí)有個(gè)游戲非要彩顯,不是彩顯不讓運(yùn)行。我就是改了這個(gè)區(qū)的某一個(gè)位,讓哪游戲“以為”我用的是彩顯,于是游戲能用了。雖然不好看,但總能用。 在DOS下,你每按一個(gè)鍵,系統(tǒng)都會(huì)記下來,下面我們一起找找這個(gè)鍵盤緩沖區(qū)的地址。知道這個(gè)地址,你就可以作一個(gè)“虛擬”鍵盤,通過發(fā)命令來模擬某個(gè)人在按鍵。這個(gè)地址位于:0040:001E。 其中每個(gè)鍵有兩個(gè)字節(jié),一個(gè)字節(jié)是A
43、SCII碼,一個(gè)是掃描碼。共16個(gè)。C:>debug-d 40:00040: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 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
44、160; 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 00 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:007
45、0 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 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
46、0B 0.0.0.0.d 90.0040:0030 30 0B 30 0B 30 0B 08 0E-08 0E 34 05 30 0B 00 00 0.0.0.4.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:0060 0F 0C 00 D4 03 29 30 7F-03 00 C0
47、 00 24 B8 11 00 .)0.$.0040:0070 00 00 00 00 00 00 00 00-14 14 14 00 01 01 01 01 .-既然是鍵盤緩沖區(qū),每個(gè)輸入的鍵都會(huì)顯示在該區(qū)中,第一次我只輸入了“d 40:0”,所以你可以在此后顯示數(shù)據(jù)右邊字符中找到這些字符,注意是間隔開的。第二次我輸入“d 0040:0000”,則右邊顯示的是“d 0040:0000”的內(nèi)容。你可以找找。 第二講 內(nèi)存映象 之所以把這個(gè)內(nèi)存單獨(dú)放一章,是為了說明它的重要性,后面的幾乎很多程序都需要你對這一章的理解。這里的內(nèi)存映象就是指當(dāng)你把一個(gè)
48、可執(zhí)行文件(EXE或COM文件)放到內(nèi)存后,整個(gè)內(nèi)存“看”起來是什么樣子的。 前面講過,這里匯編程序只能訪問1M的內(nèi)存空間,所以下面就以1M內(nèi)存為例。并且以DOS操作系統(tǒng)作為講解對象,所以所編出來的程序也僅是DOS程序。事實(shí)上,通過winasm可以訪問遠(yuǎn)遠(yuǎn)超過1M的空間,并且可以編出FOR windows的程序。但那是另外的話題。我們暫且不說那些。2.1 內(nèi)存映象 首先,這1M內(nèi)存如果我們不再以二維的方式看,而是一維的,線性地看(二維和一維的轉(zhuǎn)化方式參見前面章節(jié))。但描述還是以二維的方式描述,從最底端到最高端依次是: 1 中斷向量區(qū):該區(qū)由0000:0000
49、0000:03FF。這里存著系統(tǒng)的所有中斷的中斷向量表,對于中斷向量表,你現(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ù)對用戶是開放的,所以用戶當(dāng)然也可以從這里讀出來用。 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里。這
50、里設(shè)置在現(xiàn)在的windows 95/98/nt/me/2000/xp/2003中仍然有,所以我就不多說了。 4 用戶程序,這個(gè)當(dāng)然就是你執(zhí)行的程序了,這種程序分兩種,一種是擴(kuò)展名為com文件,一種是exe文件,從程序內(nèi)部看,前者程序的四個(gè)段重合(后面要講這四個(gè)段),所以最大長度只等于一個(gè)段,用前面段地址的理解就是com文件最大只能是64K,所以com文件只適合小的程序。而exe,四個(gè)段可任何分配,并可擴(kuò)充段,而且每個(gè)段的段地址可以任何改動(dòng),因此exe的訪問內(nèi)存能力大多了。這種格式訪問能力只受地址結(jié)構(gòu)的限制了。 用戶程序所占的內(nèi)存大小完全由程序本身
51、決定,但最大,只能到640K。這一點(diǎn),怪不得別人,只能怪當(dāng)前計(jì)算機(jī)軟硬件設(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)象對于一開始就用windows的人來說,幾乎沒見過,但對于一開始用DOS并打漢字的人來說,再正常不過。如果小于這段內(nèi)存,多余部分就空著。 5 從640K到1M-64K,這段內(nèi)存就很難說清了。這段內(nèi)存中有一部分被硬件占有,有一部分
52、是顯示緩沖區(qū)點(diǎn)有,還有一部分是系統(tǒng)ROM占有。 6 從1M-64K到1M之間的這段64K的內(nèi)存叫作HMA。這段內(nèi)存是小孩沒娘,說來話長,我們先不說他。 2.2 驗(yàn)證上面的理論2.2.1 中斷向量表 中斷向量表就是所有中斷向量首地址表,這里保存著每個(gè)中斷程序的首地址,幾乎所有的匯編書都把中斷后面后面的章節(jié)中,并且對中斷的解釋也僅從字面意思解釋,所以導(dǎo)致大學(xué)對中斷的不重要和誤解。沒耐心的沒到這個(gè)章節(jié)就不學(xué)匯編了,有耐心的到這里才豁然開朗。我現(xiàn)在不講中斷的原意。我直接告訴你,你把中斷當(dāng)成API也許更合適。也就是說,別
53、人把很多已作好的功能放到了內(nèi)存中。并且把調(diào)用這一功能的號(hào)告訴了你,你只要調(diào)用這些功能號(hào),系統(tǒng)就自動(dòng)從這個(gè)中斷向量表中找到對應(yīng)的中斷,然后執(zhí)行你的功能。 首先讓你感受一下中斷的魅力一下吧。比如中斷21H的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=100AX=2A05 BX=0000 CX=07D4 DX=0C18
54、 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ān)系,“mov ah,2a”表示調(diào)用功能號(hào)是2a號(hào)?!癷nt
55、 21”表示調(diào)用十六進(jìn)制21號(hào)中斷,“int 3”表示3號(hào)中斷,表示程序運(yùn)行到這一句時(shí)停一下?!癵=100”表示從“139D:0100 ”開始執(zhí)行。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 NC表示執(zhí)行的結(jié)果。其中CX是年,這個(gè)年是由CX中存。07D
56、4十進(jìn)制就是2004年。DH+DL=DX,所以DH=0C,DL=18。二者轉(zhuǎn)化為十進(jìn)制就是DH=12,DL=24,也就是今天了。AX=AH+AL=2A05,所以AL=05。那就是今天是星期五。上面可能你們現(xiàn)在還看不懂,不過通過解說你應(yīng)該可以知道,僅僅兩行命令,就讀到了現(xiàn)在的值?,F(xiàn)在需要作的就是把這些值提取出來用作他用了。 從中斷的作來與中斷向量表又有什么關(guān)系呢?原來你在匯編里運(yùn)行int 21時(shí),系統(tǒng)就在上面的中斷向量表中找到int 21的中斷地址,該中斷的地址應(yīng)該位于:0000:00840000:0087,具體算法前面已說明了。-d 0000:0084 00
57、870000:0080 7C 10 A7 00 |.-找到內(nèi)容是:00A7:107C。然后系統(tǒng)就
58、轉(zhuǎn)到這個(gè)地址執(zhí)行int 21。2.2.2 系統(tǒng)數(shù)據(jù)區(qū)前面都已說明過。不再多說。系統(tǒng)區(qū),很多DOS中斷程序?qū)崿F(xiàn)部分就在這個(gè)區(qū)。程序運(yùn)行區(qū)依不同的程序而不用。2.2.3 640K1M之間,這期間有些地方是ROM,有些地方是硬件的BIOS區(qū)。我僅以兩個(gè)例子說明這一區(qū)。 ROM區(qū):ROM區(qū)就是只讀內(nèi)存,也就是說這個(gè)區(qū)的數(shù)據(jù)只能讀不能寫。比如F000:0000開始的內(nèi)存是ROM。我們來寫一下,然后再看看效果。-d f000:0000 0005 '顯示由F000:0000到F000:0005的六個(gè)字節(jié)值。F000:0000 04 E8 A2 FF F9 C3
59、160; .-e f000:0000 '修改命令F000:0000 04.00 E8.00 A2.00 FF.00 F9.00 C3.0
60、0'注意,.后面的是我改的,把這幾個(gè)值都改成0了。-d f000:0000 0005 '再次顯示這個(gè)區(qū)的數(shù)據(jù)。F000:0000 04 E8 A2 FF F9 C3 .-通過上面測試,發(fā)現(xiàn)該區(qū)數(shù)據(jù)仍然
61、未改變。但你要是試別的RAM區(qū)的,肯定會(huì)變。如果想試你自己試試吧。 顯示緩沖區(qū):在文本方式下,B800:0000開始的地址保存著屏幕上每個(gè)字符位置的值。在文本方式下,屏幕被分為80 X 25。每個(gè)位置有兩個(gè)值,一個(gè)值是ASCII字符,一個(gè)值是該ASCII的屬性值(主要是顏色)。所以一個(gè)屏幕共有80X25X2=400個(gè)字符。我們來改:-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
62、. .b.8.0.0.:.B800:0010 30
63、; 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”的屬性值?,F(xiàn)在修改這些值。我把左上角的字改成黃顏色的“-”,那當(dāng)然是改b800:0001的屬性值了。-e b800:0001 0e是不是左上角的顏色變成黃色了嗎?好了,把第二個(gè)字符變成綠色的“-”吧?-e b800:0002 2d 0b變了嗎?可執(zhí)行文件內(nèi)存映象DOS下可執(zhí)行
64、文件有兩種(BAT是批處理文件,他只是簡單調(diào)用DOS內(nèi)部命令或其它程序,所以此處不認(rèn)為它是可執(zhí)行文件),一種是COM文件,一種是EXE文件,前面提到,COM文件一般小于64K。EXE文件則可以任意大。為什么呢?說到這里,還要提到段。每個(gè)段64K。段的作用就是數(shù)據(jù)組織單位。段的類型有三種:代碼段(Code Segment,簡稱CS)、數(shù)據(jù)段(Data Segment,簡稱DS)、棧段(Stack Segment,簡稱SS),另外還有一個(gè)附加數(shù)據(jù)段(Extra Segment,簡稱ES),它的用與數(shù)據(jù)段DS可以認(rèn)為完全一樣,當(dāng)數(shù)據(jù)段的64K不夠用,或你就需要把數(shù)據(jù)放到兩個(gè)段中以便移動(dòng)、復(fù)制、比較時(shí)
65、,才用到附加數(shù)據(jù)段ES。(當(dāng)然,移動(dòng)、復(fù)制、比較操作在一個(gè)段中也可以完成)。1 段的作用。1.1 代碼段(CS),程序裝入內(nèi)存中,DOS怎么知道是從哪里執(zhí)行呢?答案就是系統(tǒng)自動(dòng)從代碼段指定位置開始執(zhí)行,并且始終在代碼段中執(zhí)行。內(nèi)此代碼段CS的作用就是保存所有的指令。這里所說的代碼也就是匯編指令了。所以編寫匯編程序也就主要是編寫代碼段中的代碼。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í)際上,這是黑客編程中最重要的一部分
66、,而且系統(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)使用棧的前后使用棧,比如你在調(diào)用子程序之前入棧,而在子程序中出棧,而在系統(tǒng)調(diào)用子程序時(shí),系統(tǒng)也要使用棧,這種也將導(dǎo)致出錯(cuò)。棧就是一種先入后出(也有稱為后入先出)的結(jié)構(gòu),有地址由小到大的增加棧,有地址由大到小的逆向減棧。2 段重疊從上面,我們可以看到,CS,DS,SS三者作用各不相同,內(nèi)存就是象
67、錄音磁帶,錄新歌,則舊歌被刪,帶子上存的始終是最后錄的那段音樂。因此,如果重疊則必然相互沖突。那還能重疊嗎?這里所說的重疊不是指內(nèi)容重疊,而是指概念上的重疊,即數(shù)據(jù)相互放到一個(gè)段中,但相互可以區(qū)分開。比如某一段既有數(shù)據(jù)也有代碼,則代碼在每要執(zhí)行到數(shù)據(jù)之前加一個(gè)跳轉(zhuǎn)指令跳過這段代碼。這個(gè)跳轉(zhuǎn)指令要求用戶在編程的時(shí)候加上。而棧段呢?棧段有自己的特殊性,特殊就在于系統(tǒng)也會(huì)自動(dòng)地使用,而用戶則又在不知道系統(tǒng)在使用的情況下使用。避免這種沖突的方法就是采用逆向的棧段。2 COM文件內(nèi)存映象。 COM文件被讀到內(nèi)存中后,該文件的前100H個(gè)字節(jié)被操作系統(tǒng)使用,操作系統(tǒng)使用這256個(gè)字節(jié)保存一些系
68、統(tǒng)要使用的數(shù)據(jù),匯編語言編程者不能在這里存自己的數(shù)據(jù),但在知道這此數(shù)據(jù)的作用后可以使用其中的數(shù)據(jù)。從100H開始,就是程序的開始了。COM文件之所以最大只能有64K,其原因是COM文件的四個(gè)段是相互重疊的。也就是說,CS,DS,SS,ES四個(gè)段的地址都指向這個(gè)COM文件的100H處。程序代碼、數(shù)據(jù)、棧都在由100H到64K的區(qū)域內(nèi)。如何把三者分開呢?棧段采用逆向棧,這個(gè)棧由64K開始,隨著數(shù)據(jù)入棧,則地址就減小。這樣作的好處是,棧段由高端向低端進(jìn)展,可以詳細(xì)與數(shù)據(jù)、代碼分開;壞處也不言而喻,假如一個(gè)COM程序大量用到棧(比如是個(gè)遞歸程序)因此棧就不停地降低,而程序代碼本身也很多,甚至不停地申請
69、新空間,這樣數(shù)據(jù)和棧就會(huì)在中間碰頭,導(dǎo)致程序被破壞。 區(qū)分開數(shù)據(jù)代碼段與棧段后,下面討論把數(shù)據(jù)段和代碼段也分開。這個(gè)簡單的多,只要邏輯上分開就可以。不過一般的方法就是:在100H處放一個(gè)跳轉(zhuǎn)指令,隨后放數(shù)據(jù),然后再放置其它的代碼。而100H處的跳轉(zhuǎn)指令就跳到這里。因此,COM文件內(nèi)存映象就是:CS:0000 (由于COM的CS,DS,SS,ES三段重疊,因此此行前CS,寫成DS,SS,ES都一樣)。 CS:0100 一個(gè)跳轉(zhuǎn)到Y(jié)YYY地址的跳轉(zhuǎn)指令。CS:0101 本程序所需要用到的數(shù)據(jù)CS:XXXX 數(shù)據(jù)結(jié)束處。CS:YYYY 程序代碼保存處。CS:ZZZZ 程序代碼結(jié)束處。CS:FFFF 棧段開始處(注意棧是地址越來越小,所以這里是開始而不是結(jié)束處),也是程序的結(jié)束處。另外,此處FFFF與前面XXXX,YYY
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 老字號(hào)品牌振興計(jì)劃實(shí)施方案(參考范文)
- 《少年的你》觀后感(15篇)
- 河道生態(tài)修復(fù)工程可行性研究報(bào)告
- 工廠建設(shè)項(xiàng)目立項(xiàng)報(bào)告
- 形勢與政策關(guān)注國家大事培養(yǎng)家國情懷
- 新疆烏魯木齊市實(shí)驗(yàn)學(xué)校2023-2024學(xué)年高三上學(xué)期1月月考物理含解析
- 不跟陌生人走安全教育教案
- 廣東省部分學(xué)校2023-2024學(xué)年高三上學(xué)期11月聯(lián)考地理含解析
- 心理安全小班課件教案
- 杭州職業(yè)技術(shù)學(xué)院《學(xué)前游戲論》2023-2024學(xué)年第二學(xué)期期末試卷
- 肺結(jié)節(jié)診治中國專家共識(shí)(2024年版)解讀課件
- SCI論文寫作與投稿 第2版-課件 0-課程介紹
- 環(huán)衛(wèi)工人管理制度
- 港口擁堵緩解技術(shù)-深度研究
- 自然辯證法知到課后答案智慧樹章節(jié)測試答案2025年春浙江大學(xué)
- 房地產(chǎn)企業(yè)項(xiàng)目全過程管理標(biāo)準(zhǔn)手冊
- 《清華大學(xué)介紹》課件
- 濱州科技職業(yè)學(xué)院《遙感原理與應(yīng)用》2023-2024學(xué)年第一學(xué)期期末試卷
- 低空經(jīng)濟(jì)專業(yè)教學(xué)資源的建設(shè)與優(yōu)化策略
- 城市老舊小區(qū)智能停車場的改造規(guī)劃
- 《中藥調(diào)劑技術(shù)》課件-發(fā)藥常規(guī)與發(fā)藥交代
評(píng)論
0/150
提交評(píng)論