改錯(cuò):
(1)1kb的存儲器有1024個(gè)存儲單元,每個(gè)單元的編號是從0-1023 (2)1kb的存儲器可以存儲8*1024個(gè)bit,1024個(gè)byte (3)1GB,1MB,1KB分別是1*1024*1024*1024byte,1*1024*1024byte,1*1024 byte (4)地址總線:(8080)16根,(8088)20根,(80286)24根,(80386)32根尋址分別為:64KB,1MB,16MB,4GB (5)數(shù)據(jù)總線:(8080)8根,(8088)8根,(8086)16根,(80286)16根,(80386)32根,一次傳送的數(shù)據(jù)為:8B,8B,16B,16B,24B (6)從內(nèi)存中讀取1024字節(jié)數(shù)據(jù),8086至少要讀512次,80386至少讀取256次 (7)在存儲器中數(shù)據(jù)和程序以2進(jìn)制形式存放 匯編語言組成: 1.匯編指令:機(jī)器碼的助記符,有對應(yīng)的機(jī)器碼 2.偽指令:沒有對應(yīng)的機(jī)器碼,有編譯器執(zhí)行,計(jì)算機(jī)并不執(zhí)行 3.其他符號:如:+,-,*,/,等有編譯器識別,沒有對應(yīng)的機(jī)器碼 匯編語言的核心是匯編指令,他決定了匯編語言的特性。 存儲單元: 電子計(jì)算機(jī)的最小信息單位是bit,也就是一個(gè)二進(jìn)制位。8個(gè)bit組成一個(gè)byte,也就是通常講的一個(gè)字節(jié)。微型機(jī)存儲器的存儲單元 可以存儲一個(gè)字節(jié),即8個(gè)二進(jìn)制位。一個(gè)存儲器有128個(gè)存儲單元,它可以存儲128個(gè)字節(jié)。 cpu要想進(jìn)行數(shù)據(jù)的讀寫,必須和外部器件(芯片)進(jìn)行3類信息的交互: 1.存儲單元的地址 2.器件的選擇,讀或?qū)懙拿?控制信息) 3.讀或?qū)懙臄?shù)據(jù)(數(shù)據(jù)信息) 地址總線:指定存儲單元的; 一個(gè)cpu有N根地址線,則可以說這個(gè)cpu的地址總線的寬度為N,這樣cpu最多可以尋找2的N次方個(gè)內(nèi)存單元 數(shù)據(jù)總線:傳輸數(shù)據(jù)的 8根數(shù)據(jù)總線一次傳送一個(gè)字節(jié),16根數(shù)據(jù)總線一次可傳送2個(gè)字節(jié). 控制總線:對外部器件的控制.控制總線是一些不同控制線的集合。有多少跟 控制線,就意味著cpu提供了對外部器件的多少種控制??刂瓶偩€決定cpu對外部器件的控制能力. 運(yùn)算器進(jìn)行信息處理;寄存器進(jìn)行信息存儲;控制器控制各種器件進(jìn)行工作;內(nèi)部總線連接各種器件,在它們之間進(jìn)行數(shù)據(jù)的傳送。 8086CPU有14個(gè)寄存器,每個(gè)寄存器有一個(gè)名稱。都是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,DS,ES,PSW. 8086CPU所有寄存器都是16位的,可以存放兩個(gè)字節(jié)。AX,BX,CX,DX四個(gè)寄存器通常用來存放一般性的數(shù)據(jù),被稱為通用寄存器。 8086CPU的AX,BX,CX,DX四個(gè)寄存器都可分為兩個(gè)獨(dú)立使用的8位寄存器來用: AX 可分為AH,AL BX 可分為BH,BL CX 可分為CH,CL DX 可分為DH,DL 字在寄存器中的存儲 字節(jié):記為byte,一個(gè)字節(jié)由8個(gè)比特組成,可以存在8位寄存器中 字:記為word,一個(gè)字有兩個(gè)字組成,這兩個(gè)字節(jié)分別成為這個(gè)字的高位字節(jié)和低位字節(jié)。 在進(jìn)行數(shù)據(jù)傳送或運(yùn)算時(shí),要注意指令的兩個(gè)操作對象的位數(shù)應(yīng)當(dāng)是一致的。 CPU通過地址總線送入存儲器的必須是一個(gè)內(nèi)存單元的物理地址。在CPU向地址總線上發(fā)送物理地址之前,必須在內(nèi)部先行成這個(gè)物理地址。不同的CPU有不同的形成物理地址的方式。 8086CPU要讀寫內(nèi)存時(shí): (1)CPU中的相關(guān)部件提供兩個(gè)16為地址,一個(gè)稱為段地址,另一個(gè)稱為偏移地址; (2)段地址和偏移地址通過內(nèi)部總線送入一個(gè)稱為地址加法器的部件; (3)地址加法器將兩個(gè)16位地址合成為一個(gè)20位的物理地址; (4)地址加法器通過內(nèi)部總線將20位物理地址送入輸入輸出控制電路; (5)輸入輸出控制電路將20位物理地址送上地址總線; (6)20位物理地被地址總線傳送到存儲器. 地址加法器采用物理地址=段地址*16+偏移地址的方法合成物理地址. "段地址*16+偏移地址=物理地址"的的本質(zhì)含義是:CPU在訪問內(nèi)存時(shí),用一個(gè)基礎(chǔ)地址(段地址*16)和一個(gè)相對于基礎(chǔ)地址的偏移地址相加,給出內(nèi)存單元的物理地址. 由于8086CPU用"基礎(chǔ)地址(段地址*16)+偏移地址=物理地址"的方式給出內(nèi)存單元的物理地址,使得我們可以用分段的方式來管理內(nèi)存 有兩點(diǎn)需要注意:段地址*16必然是16的倍數(shù),所以一個(gè)段的起始地址也一定是16的倍數(shù):偏移地址為16為,16為地址的尋址能力為64KB,所以一個(gè)段的長度最大為64KB 段寄存器: 8086cpu有4個(gè)段寄存器:CS,DS,SS,ES;當(dāng)8086CPU要訪問內(nèi)存時(shí)由這4個(gè)寄存器提供內(nèi)存單元的段地址。 CS和IP是8086CPU中兩個(gè)最關(guān)鍵的寄存器,他們指示了CPU當(dāng)前要讀取得指令的地址。CS為代碼段寄存器,IP為指令指針寄存器,從名稱上看出他們和指令的關(guān)系 在8086PC機(jī)中,任意時(shí)刻,設(shè)CS中的內(nèi)容為M, IP中的內(nèi)容為N,8086CPU將從內(nèi)存M*16+N單元開始,讀取一條指令并執(zhí)行。 "段地址*16+偏移地址=物理地址"的的本質(zhì)含義是:CPU在訪問內(nèi)存時(shí),用一個(gè)基礎(chǔ)地址(段地址*16)和一個(gè)相對于基礎(chǔ)地址的偏移地址相加,給出內(nèi)存單元的物理地址. 由于8086CPU用"基礎(chǔ)地址(段地址*16)+偏移地址=物理地址"的方式給出內(nèi)存單元的物理地址,使得我們可以用分段的方式來管理內(nèi)存 有兩點(diǎn)需要注意:段地址*16必然是16的倍數(shù),所以一個(gè)段的起始地址也一定是16的倍數(shù):偏移地址為16為,16為地址的尋址能力為64KB,所以一個(gè)段的長度最大為64KB 段寄存器: 8086cpu有4個(gè)段寄存器:CS,DS,SS,ES;當(dāng)8086CPU要訪問內(nèi)存時(shí)由這4個(gè)寄存器提供內(nèi)存單元的段地址。 CS和IP是8086CPU中兩個(gè)最關(guān)鍵的寄存器,他們指示了CPU當(dāng)前要讀取得指令的地址。CS為代碼段寄存器,IP為指令指針寄存器,從名稱上看出他們和指令的關(guān)系 在8086PC機(jī)中,任意時(shí)刻,設(shè)CS中的內(nèi)容為M, IP中的內(nèi)容為N,8086CPU將從內(nèi)存M*16+N單元開始,讀取一條指令并執(zhí)行。 8086CPU的工作過程可以簡要描述如下: (1)從CS:IP指向內(nèi)存單元讀取指令,讀取得指令進(jìn)入指令緩沖器; (2)IP=IP+所讀取指令的長度,從而指向下一條指令; (3)執(zhí)行指令,轉(zhuǎn)到步驟(1). 在8086CPU加電啟動(dòng)或復(fù)位后(即CPU剛開始工作時(shí))CS和IP被設(shè)置為CS=F000H.IP=FFFFH,即8086機(jī)剛啟動(dòng)時(shí),CPU從內(nèi)存FFFF0H單元中讀取指令執(zhí)行,F(xiàn)FFF0H單元中的指令時(shí)8086CPU開機(jī)后執(zhí)行的第一條指令 我們可以說,CPU將CS:IP指向的內(nèi)存單元中的內(nèi)容看作指令,因?yàn)?,在任何時(shí)候,CPU將CS,IP中的內(nèi)容當(dāng)作指令的段地址和偏移地址,用他們合成指令的物理地址,到內(nèi)存中讀取指令碼,執(zhí)行。如果說,內(nèi)存中的一段信息曾被CPU執(zhí)行過的話,那么,他說在的內(nèi)存單元必然被CS:IP指向過。 MOV指令被稱為傳送指令。 能夠改變CS,IP的內(nèi)容的指令被稱為轉(zhuǎn)移指令,如(JMP指令)修改CS,IP的內(nèi)容:"JMP 段地址:偏移地址" JMP 2AE3:3,執(zhí)行后,CS=2AE3H.IP=0003H,CPU將從2AE33H出讀取指令。 JMP段地址:偏移地址 指令的功能為:用指令中給出的段地址修改CS, 偏移地址修改IP 若想僅修改IP的內(nèi)容,可用指令"JMP某一合法寄存器"完成。 JMP ax,指令執(zhí)行前:AX=1000H.CS=2000H,IP=0003H 指令執(zhí)行后:AX=1000H.CS=2000H,IP=1000H JMP bx,指令執(zhí)行前:BX=0B16H.CS=2000H,IP=0003H 指令執(zhí)行后:BX=0B16H.CS=2000H,IP=0B16H JMP AX,在含義上類似MOV IP.AX這樣的指令。 (2)Debug功能: *R命令查看,改變CPU寄存器的內(nèi)容; *D命令查看內(nèi)存中的內(nèi)容; *E命令改寫內(nèi)存中的內(nèi)容 *U命令將內(nèi)存中的機(jī)器指令翻譯成匯編指令 *T命令執(zhí)行一條機(jī)器指令; *A命令以匯編指令的格式在內(nèi)存中寫入一條機(jī)器指令. 從內(nèi)存的角度繼續(xù)學(xué)習(xí)寄存器; 字單元,即存放一個(gè)字型數(shù)據(jù)(16位)的內(nèi)存單元,由兩個(gè)地址連續(xù)的內(nèi)存單元組成,高地址內(nèi)存單元存放字型數(shù)據(jù)的高位字節(jié),低地址內(nèi)存單元中存放字型數(shù)據(jù)的低位字節(jié). 我們將起始地址為N的字單元簡稱為N地址字單元,比如一個(gè)字單元由2,3兩個(gè)內(nèi)存單元組成,則這個(gè)內(nèi)存單元組成,則這個(gè)字單元的起始地址為2,我們可以說這是2地址字單元 DS:通常用來存放要訪問數(shù)據(jù)的段地址. 數(shù)據(jù)段的段地址默認(rèn)放在ds中,指令執(zhí)行時(shí),CPU會自動(dòng)從DS中取出. 8086CPU不支持將數(shù)據(jù)直接送入段寄存器的操作(這屬于8086CPU硬件設(shè)計(jì)問題),可以用一個(gè)寄存器來進(jìn)行中專,即先將1000H送入一個(gè)一般的寄存器,如bx,在將bx中的內(nèi)容送入ds cs(code segment)是代碼段寄存器,放代碼段的段地址他里面的內(nèi)容和ip里面的內(nèi)容和起來就可以找到當(dāng)前執(zhí)行的指令, ds(data segment)是數(shù)據(jù)段段寄存器 放數(shù)據(jù)段的段地址,根據(jù)段地址*16d+偏移量就可以得到物理地址 從內(nèi)存單元到寄存器的格式是:"MOV 寄存器名,內(nèi)存單元地址",從寄存器到內(nèi)存單元?jiǎng)t是:"MOV 內(nèi)存單元地址,寄存器名"。 MOV 指令可以有以下幾種形式: MOV 寄存器,數(shù)據(jù) MOV 寄存器,寄存器 MOV 寄存器,內(nèi)存單元 MOV 內(nèi)存單元,寄存器 MOV 段寄存器,寄存器 MOV 寄存器,段寄存器 MOV 內(nèi)存單元,段寄存器 MOV 段寄存器,內(nèi)存單元 ADD: ADD 寄存器,數(shù)據(jù) ADD 寄存器,寄存器 ADD 寄存器,內(nèi)存單元 ADD 內(nèi)存單元,寄存器 數(shù)據(jù)段小結(jié): 1字在內(nèi)存中存儲時(shí),要用兩個(gè)連續(xù)的內(nèi)存單元來存放,字的地位字節(jié)存放在低地址單元中,高字節(jié)存放在高地址單元中。 2用MOV指令要訪問內(nèi)存單元,可以在MOV指令中只給出單元的偏移地址,此時(shí),段地址默認(rèn)在DS寄存器中. 3[address]表示一個(gè)偏移地址為address的內(nèi)存單元。 4在內(nèi)存中和寄存器之間傳送字型數(shù)據(jù)時(shí),高地址單元和高8位寄存器,低地址單元和低8位寄存器相對應(yīng)。 5MOV,ADD,SUB是具有兩個(gè)操作對象的指令,JMP是具有一個(gè)操作對象的指令 棧: 8086CPU中,有兩個(gè)寄存器,段寄存器SS和寄存器SP,棧頂?shù)亩蔚刂反娣旁赟S中,偏移地址存放在SP中,任意時(shí)刻,SS:SP指向棧頂元素。PUSH指令和POP指令執(zhí)行時(shí),CPU從SS和SP得到棧頂?shù)牡刂? PUSH AX的執(zhí)行,由以下兩步完成: (1) SP=SP-2,SS:SP指向當(dāng)前棧頂前面的單元,以當(dāng)前棧頂前面的單元為新的棧頂; (2) 將AX中的內(nèi)容送入SS:SP指向的內(nèi)存單元處,SS:SP此時(shí)指向新棧頂 (注意: 入棧時(shí),棧頂從高地址向底地址方向增長) POP AX的執(zhí)行過程和PUSH AX剛好相反 (1) 將SS:SP指向的內(nèi)存單元處的數(shù)據(jù)送入AX中 (2) SP=SP+2,SS:SP指向當(dāng)前棧頂下面的單元,以當(dāng)前棧頂下面的單元為新的棧頂. (注意: 圖中,出棧后,SS:SP指向新的棧頂1000EH,POP操作前的棧頂元素,1000CH處的2266H依然存在,但是,它已不在棧中.當(dāng)再次執(zhí)行PUSH等入棧指令后,SS:SP移至1000CH,并在里面寫入新的數(shù)據(jù),它將覆蓋.) 棧頂超界問題: 80886CPU不保證我們對棧的操作不會超界. PUSH,POP指令是可以在寄存器和內(nèi)存之間傳送數(shù)據(jù)的. PUSH 寄存器;將一個(gè)寄存器中的數(shù)據(jù)入棧 POP 寄存器;出棧.用一個(gè)寄存器收入棧的數(shù)據(jù) PUSH 段寄存器 ;將一個(gè)段寄存器中的數(shù)據(jù)入棧 POP 段寄存器 ;出棧,用一個(gè)段寄存器收入棧的數(shù)據(jù) PUSH 內(nèi)存單元;將一個(gè)內(nèi)存單元處的字入棧(注意:棧操作都是以字為單位.) POP 內(nèi)存單元;出棧,用一個(gè)內(nèi)存字單元接收出棧的數(shù)據(jù) 指令執(zhí)行時(shí),CPU要知道內(nèi)存單元的地址.可以在PUSH,POP指令中給出內(nèi)存單元的偏移地址,段地址在指令執(zhí)行時(shí),CPU從DS中取得. 注意:PUSH ,POP等棧操作指令,修改的只是SP,也就是說,棧頂?shù)淖兓秶畲鬄?--FFFFH 棧段: PUSH,POP等指令再執(zhí)行的時(shí)候只修改SP,所以棧頂?shù)淖兓秶?--FFFFH,從??諘r(shí)候的SP=0,一直壓棧.直到棧滿時(shí)SP=0;如果再次壓棧.棧頂將環(huán)繞.覆蓋了原來?xiàng)V械膬?nèi)容.所以棧的容量最大為64KB 注意:Debug的T命令在執(zhí)行修改寄存器SS的指令時(shí),下一條指令也緊接著被執(zhí)行. 補(bǔ)充: Debug使用: Debug在執(zhí)行D命令時(shí),將段地址送入 DS中.D命令也是提供了一種符合CPU機(jī)理的格式."D段寄存器:偏移地址",以段寄存器中的數(shù)據(jù)為段地址SA,列出從SA:偏移地址開始的內(nèi)存區(qū)間中的數(shù)據(jù) -D DS:10 18 ;-D CS:0 ;-D SS:0 E,A,U命令中使用段寄存器 在E,A,U這些可以帶有內(nèi)存單元地址的命令中,也可以同D命令一樣,用段寄存器表示內(nèi)存單元的段地址 一個(gè)源程序從寫出到執(zhí)行的過程 1編寫匯編源程序(產(chǎn)生一個(gè)存儲源程序的文本文件) 2 對源程序進(jìn)行編譯連接 [1]匯編編譯程序?qū)υ闯绦蛭募械脑闯绦蜻M(jìn)行編譯,產(chǎn)生目標(biāo)文件 [2]再用連接程序?qū)δ繕?biāo)文件進(jìn)行連接,生成可在操作系統(tǒng)中直接運(yùn)行的可執(zhí)行文件 可執(zhí)行文件包含兩部分內(nèi)容: *程序(從源程序中的匯編指令翻譯過來的機(jī)器碼)和數(shù)據(jù)(源程序中定義的數(shù)據(jù)) *相關(guān)的描述信息(比如,程序有多大,要占用多少內(nèi)存空間等) 3 執(zhí)行可執(zhí)行文件中的程序 偽指令:由編譯器來執(zhí)行的指令 (1)XXX segment ...... XXX ends (2)END (匯編程序的結(jié)束標(biāo)記) (3)Assume(假設(shè))將有特定用途的段和相關(guān)的段寄存器關(guān)聯(lián)起來即可 源程序中的"程序"(我們這里所說的程序就是指源程序中最終有計(jì)算機(jī)執(zhí)行,處理的指令或數(shù)據(jù)) 注意(將源程序文件中的所有內(nèi)容稱為源程序,將源程序中最終由計(jì)算機(jī)執(zhí)行,處理的指令或數(shù)據(jù),稱為程序.程序最先以匯編指令的形式存在源程序中,經(jīng)編譯,連接后轉(zhuǎn)變?yōu)闄C(jī)器碼,存儲在可執(zhí)行文件中.) 標(biāo)號:一個(gè)標(biāo)號指代一個(gè)地址 與結(jié)束相關(guān)的概念區(qū)別: 通知編譯器一個(gè)段結(jié)束 相關(guān)指令[段名 Ends ] 指令性質(zhì) [偽指令] 由編譯器執(zhí)行 通知編譯器程序結(jié)束 相關(guān)指令[ End ] 指令性質(zhì) [偽指令] 由編譯器執(zhí)行 程序返回 相關(guān)指令[ Mov ax,4c00H int 21H ] 指令性質(zhì)[匯編指令]由CPU執(zhí)行 生成程序最后連接的作用: *當(dāng)源程序很大時(shí),可以將它分為多個(gè)源程序文件來編譯,每個(gè)源程序編譯成為目標(biāo)文件后,再用連接程序?qū)⑺鼈冞B接到一起,生成一個(gè)可執(zhí)行文件. *程序中調(diào)用了某個(gè)庫文件中的子程序,需要將這個(gè)庫文件和該程序生成的目標(biāo)文件連接到一起,生成一個(gè)可執(zhí)行文件 *一個(gè)源程序編譯后,得到了存有機(jī)器碼的目標(biāo)文件,目標(biāo)文件的有些內(nèi)容還不能直接用來生成可執(zhí)行文件,連接程序?qū)⑦@些內(nèi)容處理為最終的可執(zhí)行信息.所以,在只有一個(gè)源程序文件,而又不許要某個(gè)庫中的子程序的情況下,也必須用連接程序?qū)δ繕?biāo)文件進(jìn)行處理,生成可執(zhí)行文件. 操作系統(tǒng)的外殼 操作系統(tǒng)是由多個(gè)功能模塊組成的龐大,復(fù)雜的軟件系統(tǒng).任何通用的操作系統(tǒng),都要提供一個(gè)稱為shell(外殼)的程序,用戶(操作人員)使用這個(gè)程序來操作計(jì)算機(jī)系統(tǒng)進(jìn)行工作. DOS中有一個(gè)程序command.com.這個(gè)程序在DOS中稱命令解釋器,也就是DOS系統(tǒng)的Shell. DOS啟動(dòng)時(shí),先完成其他重要的初始化工作.然后運(yùn)行command.com.command.com運(yùn)行后,執(zhí)行完其他的相關(guān)任務(wù)后,再屏幕顯示出由當(dāng)前盤符和當(dāng)前路徑組成的提示符,比如:"C:\"或者"c:\windows"等,然后等待用戶的輸入 用戶可以輸入所要執(zhí)行的命令比如:cd,dir,type等.這些命令由command執(zhí)行.command執(zhí)行完這些命令后,再次顯示由當(dāng)前盤符和當(dāng)前路徑組成的提示符,等待用戶的輸入. 如果用戶要執(zhí)行一個(gè)程序,則輸入該程序的可執(zhí)行文件的名稱,command將該文件裝入內(nèi)存,設(shè)置CS:IP指向程序的入口.此后,command暫停運(yùn)行,CPU運(yùn)行程序結(jié)束后,返回command中, Command再次顯示由當(dāng)前盤符和當(dāng)前路徑組成的提示符,等待用戶的輸入. 匯編程序從寫到執(zhí)行的過程 "()"描述性的符號來表示一個(gè)寄存器或一個(gè)內(nèi)存單元中的內(nèi)容 (ax)表示ax中的內(nèi)容,(al)表示al中的內(nèi)容 "()"中的內(nèi)存單元的地址為物理地址 注意:"()"中元素可以有三種類型:*寄存器名;*段寄存器名;(3)內(nèi)存單元的物理地址(一個(gè)20為數(shù)據(jù))。比如:(ax),(ds),(al),(cx),(20000H),((ds)*16+(bx))等是正確的用法; (2000H),(2000:0),((ds):1000H)等不是正確的用法 一些應(yīng)用: (1) ax中的內(nèi)容為0010H,可以這樣描述:(ax)=0010H; (2) 2000:1000處的內(nèi)容為0010H,可以描述(21000H)=0010H (3) 對于MOV AX,[2]的功能,可以描述:(AX)=((DS)*16+2); (4) MOV [2],AX的功能,可以描述((DS)*16+2)=(AX); (5) 對于ADD AX,2的功能,可以描述(AX)=(AX)+2; (6) 對于ADD AX,BX的功能,可以描述(AX)=(AX)+(BX); (7) 對于PUSH AX的功能,可以描述 (SP)=(SP)-2 ((SS)*16+(SP))=(AX) (8) 對于POP AX的功能,可以描述: (AX)=((SS)*16+(SP)) (SP)=(SP)+2 LOOP指令 LOOP 標(biāo)號; 步驟: 1,(CX)=(CX)-1 2 判斷CX中的值,不為零則轉(zhuǎn)至標(biāo)號處執(zhí)行程序,如果為零則想下執(zhí)行 CX和LOOP指令想配合實(shí)現(xiàn)循環(huán)功能的三個(gè)要點(diǎn): (1)在CX中存放循環(huán)次數(shù); (2)LOOP指令中的標(biāo)號所標(biāo)志地址要在前面; (3)要循環(huán)執(zhí)行的程序段,要寫在標(biāo)號和loop指令的中間 程序框架: MOV CX,循環(huán)次數(shù) S: 循環(huán)執(zhí)行的程序段 LOOP S 匯編程序中指令的含義: "MOV AL,[0]"含義:(AL)=0.將常量0送入al中(與MOV AL,0含義相同); "MOV AL,DS:[0]",含義:AL=((DS)*16+0),將內(nèi)存單元中的數(shù)據(jù)送入AL中 ; "MOV AL,[BX]",含義:AL=((DS)*16+(BX)),將內(nèi)存單元中的數(shù)據(jù)送入AL中; "MOV AL,DS:[BX]",含義:與"MOV AL,[BX]"相同. 我們可以看出: 1,在匯編源程序中,如果用指令訪問一個(gè)內(nèi)存單元,則在指令中必須用"[...]"來表示內(nèi)存單元,如果在"[]"里用一個(gè)常量idata直接給出內(nèi)存單元的偏移地址,就要在"[]"的前面顯式地給出段地址所在的段寄存器 2 如果在"[]"里用寄存器,比如bx,間接給出內(nèi)存單元的偏移地址,則段地址默認(rèn)在ds中,當(dāng)然,也可以顯式地給出段地址所在的段寄存器. DOS方式下,一般情況,0:200-0:300空間中沒有系統(tǒng)或其他程序的數(shù)據(jù)或代碼 將一個(gè)字符串"BaSic"的大寫字母轉(zhuǎn)變?yōu)樾?,小寫轉(zhuǎn)變?yōu)榇髮懙膬煞N方法: 1將用到And和Or指令 2用到加減指令 數(shù)學(xué)化的描述為 :(AX)=((DS)*16+(BX)+200) 指令的幾種形式: MOV AX,[200+BX] MOV AX,200[BX] MOV AX,[BX].200 SI和DI是8086CPU中和 BX功能相近的寄存器,SI和DI不能夠分成兩個(gè)8為寄存器來使用 數(shù)學(xué)化描述:(AX)=((DS)*16+(BX)+(SI)) 該指令也可以寫成如下格式(常用): MOV AX.[BX][SI] 數(shù)學(xué)化的描述:(AX)=((DS)*16+(BX)+(SI)+IDATA) 該指令也可以寫成如下格式(常用): MOV AX,[BX+20+SI] MOV AX,200[BX][SI] MOV AX,[BX].200[SI] MOV AX,[BX][SI].200 REG的集合包括:AX,BX,CX,DX,AH,Al,BH,Bl,CH,CL,DH,DL,SP,BP,SI,DI; SREG的集合包括:DS,SS,CS,ES 總結(jié):8086CPU中, (1)只有4個(gè)寄存器可以在"[]"中來進(jìn)行內(nèi)存單元的尋址(BX,SI,BP,DI) 這些是錯(cuò)誤的指令: MOV AX,[CX] MOV AX,[AX] MOV AX,[DX] MOV AX,[DS] (2)在[..]中,這4個(gè)寄存器可以單個(gè)出現(xiàn),或只能以4種組合出現(xiàn):BX和SI,BX和DI ,BP和SI,BP和DI (3)只要在[..]中使用寄存器BP,而指令中沒有顯性的給出段地址,段地址就默認(rèn)在SS中 指令在執(zhí)行前,所要處理的數(shù)據(jù)可以在三個(gè)地方:CPU內(nèi)部,內(nèi)存,端口 匯編語言中的數(shù)據(jù)位置的表達(dá): (1)立即數(shù)(idata) 對于直接包含在機(jī)器指令中的數(shù)據(jù)(執(zhí)行前在CPU的指令緩沖器中),在匯編語言中稱:立即數(shù)(idata),在匯編指令中直接給出 (2)寄存器 指令要處理的數(shù)據(jù)在寄存器中,在匯編指令中給出相應(yīng)的寄存器名; (3)段地址(SA)和偏移地址(EA) 指令要處理的數(shù)據(jù)在內(nèi)存中,在匯編指令中可用[X]的格式給出EA,SA在某個(gè)段寄存器中 尋址方式: 8086CPU的指令,處理兩種尺寸的數(shù)據(jù),BYTE和WORD (1)通過寄存器名指明要處理的數(shù)據(jù)的尺寸 (2)在沒有寄存器名的情況下,用操作符X ptr指明內(nèi)存單元的長度,X在匯編指令中可以為WORD或BYTE 如:MOV WORD PTR DS:[0],1 (3)其他方法 有些指令已經(jīng)默認(rèn)了訪問的是字單元還是字節(jié)單元,比如:PUSH[1000H]就不用指明訪問的是字單元還是字節(jié)單元,因?yàn)镻USH指令只進(jìn)行字操作 DIV指令(除法) (1):除數(shù):有8位和16位兩種,在一個(gè)寄存器或內(nèi)存單元中 (2)被除數(shù):默認(rèn)放在AX或DX和AX中, 如果除數(shù)為8位,被除數(shù)則為16位,默認(rèn)在AX中存放, 如果除數(shù)為16位,被除數(shù)則為32位,在 DX和AX中存放,DX存放高16位, AX存放低16位 (3)結(jié)果: 如果除數(shù)為8位,則 AL存儲除法操作的商,AH存儲除法操作的余數(shù) 如果除數(shù)為16位,則AX存儲除法操作的商,DX存儲除法操作的余數(shù) 格式: DIV REG DIV 內(nèi)存單元 偽指令DD DD是用來定義DWORD(DOUBLE WORD,雙字)型數(shù)據(jù)的 DUP操作符 在匯編中同DB,DW,DD等一樣,也是由編譯器識別處理的符號,它和DB,DW,DD等數(shù)據(jù)定義偽指令配合使用的,用來進(jìn)行數(shù)據(jù)的重復(fù); DB 重復(fù)的次數(shù) DUP(重復(fù)的字節(jié)型數(shù)據(jù)) DW 重復(fù)的次數(shù) DUP(重復(fù)的字型數(shù)據(jù)) DD 重復(fù)的次數(shù) DUP(重復(fù)的雙字?jǐn)?shù)據(jù)) 可以修改IP,或同時(shí)修改CS和IP的指令統(tǒng)稱為轉(zhuǎn)移指令,轉(zhuǎn)移指令就是可以控制CPU執(zhí)行內(nèi)存中某處的代碼的指令 8086CPU的轉(zhuǎn)移行為有一下幾類: #只修改IP時(shí),程為段內(nèi)轉(zhuǎn)移,比如:JMP AX #同時(shí)修改CS和IP時(shí),稱段間轉(zhuǎn)移,比如:JMP 1000:0 由于轉(zhuǎn)移指令對IP的修改范圍不同,段內(nèi)轉(zhuǎn)移又分為:短轉(zhuǎn)移和近轉(zhuǎn)移 #短轉(zhuǎn)移IP的修改范圍為-128-127 #近轉(zhuǎn)移IP的修改范圍為-32768-32768 8086CPU的轉(zhuǎn)移指令分 #無條件轉(zhuǎn)移指令(JMP) #條件轉(zhuǎn)移指令 #循環(huán)指令(LOOP) #過程 #中斷 操作符offset 在匯編語言中是由編譯器處理的符號,它的功能是取得標(biāo)號的偏移地址 JMP 為無條件轉(zhuǎn)移指令,可以只修改IP,也可以同時(shí)修改CS和IP JMP指令要給出兩種信息 #轉(zhuǎn)移的目的地址 #轉(zhuǎn)移的距離(段間轉(zhuǎn)移,段內(nèi)短轉(zhuǎn)移,段內(nèi)近轉(zhuǎn)移) 不同的給出目的地址的方法,和不同的轉(zhuǎn)移位置,對應(yīng)有不同的格式的JMP指令 依據(jù)位移進(jìn)行轉(zhuǎn)移的JMP指令 JMP SHORT 標(biāo)號(轉(zhuǎn)到標(biāo)號處執(zhí)行指令) 這種格式的JMP指令實(shí)現(xiàn)的是段內(nèi)短轉(zhuǎn)移,它對IP的修改范圍為-128-127,也就是是說,它向前轉(zhuǎn)移時(shí)可以最多超越128個(gè)字節(jié),向后轉(zhuǎn)移可以最多超過127個(gè)字節(jié)。JMP指令中的"short"符號,說明指令進(jìn)行的是短轉(zhuǎn)移。JMP指令中的"標(biāo)號"是代碼段中的標(biāo)號,指明了指令要轉(zhuǎn)移的目的地,轉(zhuǎn)移指令結(jié)束后, CS:IP應(yīng)該指向標(biāo)號處的指令 CPU在執(zhí)行JMP指令的時(shí)候并不需要轉(zhuǎn)移的目的地址 在"JMP SHORT 標(biāo)號"指令所對應(yīng)的機(jī)器碼中,并不包含轉(zhuǎn)移的目的地址,而是包含的是轉(zhuǎn)移的位移,這個(gè)位移,是編譯器根據(jù)匯編指令中的"標(biāo)號"計(jì)算出來的 實(shí)際上,指令"JMP SHORT 標(biāo)號"的功能為:(IP)=(IP)+8位位移 (1)8位位移="標(biāo)號"處的地址-JMP指令后的第一個(gè)字節(jié)的地址 (2)SHORT 指明此處的位移為8位位移 (3)8位位移的范圍為-128-127,用補(bǔ)碼表示; (4)8位位移由編譯程序在編譯時(shí)算出 還有一種和指令"JMP SHORT 標(biāo)號"功能相近的指令格式:JMP NEAR PTR 標(biāo)號,它實(shí)現(xiàn)的是段內(nèi)近轉(zhuǎn)移 指令"JMP NEAR PTR標(biāo)號"的功能為:(IP)=(IP)+16位位移 (1)16位位移=指令"標(biāo)號"處的地址-JMP指令后的第一個(gè)字節(jié)的地址 (2)NEAR PTR指明此處的位移為16位位移,進(jìn)行的是段內(nèi)近轉(zhuǎn)移; (3)16位位移的范圍為-32768-32767,用補(bǔ)碼表示; (5)16位位移由編譯程序在編譯時(shí)算出。 上面是相對于當(dāng)前IP的轉(zhuǎn)移位移 指令"JMP FAR PTR 標(biāo)號"實(shí)現(xiàn)的是段間轉(zhuǎn)移(遠(yuǎn)轉(zhuǎn)移) (CS)=標(biāo)號所在的段的段地址;(IP)=標(biāo)號在段中的偏移地址 。 FAR PTR指明了指令用標(biāo)號的段地址和偏移地址修改CS和IP 轉(zhuǎn)移地址在寄存器中的JMP指令 JMP 16為寄存器 功能:(IP)=(16位寄存器) 轉(zhuǎn)移地址在內(nèi)存中的JMP指令 (1)JMP WORD PTR 內(nèi)存單元地址(段內(nèi)轉(zhuǎn)移) 功能:從內(nèi)存單元地址處開始存放著一個(gè)字,是轉(zhuǎn)移的目的偏移地址 (2)JMP DWORD PTR 內(nèi)存單元地址(段間轉(zhuǎn)移) 功能:從內(nèi)存單元地址開始存放著兩個(gè)字,高地址的字是轉(zhuǎn)移的目的段地址,低地址處是轉(zhuǎn)移的目的偏依地址 (CS)=(內(nèi)存單元地址+2) (IP)=(內(nèi)存單元地址) JCXZ指令(有條件轉(zhuǎn)移指令,所有的有條件轉(zhuǎn)移指令都是短轉(zhuǎn)移,在對應(yīng)的機(jī)器碼中包含轉(zhuǎn)移的位移,而不是目的地址,對IP的修改范圍都為:-128-127) 指令格式:JCXZ 標(biāo)號(如果(CX)=0,轉(zhuǎn)移到標(biāo)號處執(zhí)行) 操作:當(dāng)(CX=0)時(shí),(IP)=(IP)+8位位移 8位位移="標(biāo)號"處的地址-JCXZ指令后的第一個(gè)字節(jié)的地址 8位位移的范圍為-128-127,用補(bǔ)碼表示 8位位移由編譯程序在編譯時(shí)算出 當(dāng)(CX)!=0時(shí),程序向下執(zhí)行(相當(dāng)于if(CX)==0 JMP SHORT 標(biāo)號) LOOP指令循環(huán)指令,所有的循環(huán)指令都是短轉(zhuǎn)移,在對應(yīng)的機(jī)器碼中包含轉(zhuǎn)移的位移,而不是目的地址,對IP的修改范圍都為-128-127 指令格式:LOOP 標(biāo)號((CX)=(CX)-1,如果(CX)!=0,轉(zhuǎn)移到標(biāo)號處執(zhí)行) 操作: (1)(CX)=(CX)-1; (2)如果(CX)!=0,(IP)=(IP)+8位位移 8位位移="標(biāo)號"處的地址-JCXZ指令后的第一個(gè)字節(jié)的地址 8位位移范圍為-128-127,用補(bǔ)碼表示 8位位移由編譯程序在編譯時(shí)算出 如果(CX=0),程序向下執(zhí)行 功能相當(dāng)于 (CX)--; If((CX)!=0)JMP SHORT 標(biāo)號 編譯器可對轉(zhuǎn)移位移超界檢測 一個(gè)字符在顯示緩沖區(qū)中要占兩個(gè)字節(jié),分別存放字符的ASCII碼和屬性,低位字節(jié)存儲字符的ASCII碼,高位字節(jié)存儲字符的屬性 一個(gè)在屏幕上顯示的字符,具有前景色(字符色)和背景色,字符可以高亮度和閃爍的方式顯示,前景色,背景色,閃爍,高亮等信息被記錄在屬性字節(jié)中。 CALL 和 RET指令 都是轉(zhuǎn)移指令,都修改IP,或同時(shí)修改CS和IP RET指令用棧中的數(shù)據(jù),修改IP的內(nèi)容,從而實(shí)現(xiàn)近轉(zhuǎn)移; RETF指令用棧中的數(shù)據(jù),修改CS和IP的內(nèi)容,從而實(shí)現(xiàn)遠(yuǎn)轉(zhuǎn)移 CPU執(zhí)行RET指令時(shí),進(jìn)行下面操作: (1) (IP)=((SS)*16+(SP)) (2) (SP)=(SP)+2 CPU執(zhí)行RETF指令時(shí),進(jìn)行下面操作: (1)(IP)=((SS)*16+(SP)) (2)(SP)=(SP)+2 (3)(CS)=((SS)*16+(SP)) (4)(SP)=(SP)+2 CPU執(zhí)行CALL指令時(shí),進(jìn)行下面操作: (1)將當(dāng)前的IP或CS和IP壓入棧中 (2)轉(zhuǎn)移 CALL指令不能實(shí)現(xiàn)短轉(zhuǎn)移,除此,CALL指令實(shí)現(xiàn)轉(zhuǎn)移的方法和JMP指令的原理相同 根據(jù)位移進(jìn)行轉(zhuǎn)移的CALL指令 執(zhí)行CALL指令的一種格式, (1)(SP)=(SP)-2 ((SS)*16+(SP))=(IP) (2)(IP)=(IP)+16位位移 16位位移="標(biāo)號"處的地址-CALL指令后的第一個(gè)字節(jié)的地址 16位位移范圍-32768-32768 16位位移由編譯器在編譯時(shí)算出 轉(zhuǎn)移的目的地址在指令中的CALL指令 前面的CALL指令,其對應(yīng)的機(jī)器指令中并沒有轉(zhuǎn)移的目的地址,而是相對于當(dāng)前IP的轉(zhuǎn)移位移 指令"CALL FAR PTR標(biāo)號"實(shí)現(xiàn)的是段間轉(zhuǎn)移 (1)(SP)=(SP)-2 ((SS)*16+(SP))=(CS) (SP)=(SP)-2 ((SS)*16+(SP))=(IP) (2)(CS)=標(biāo)號所在段的段地址 (IP)=標(biāo)號在段中的偏移地址 轉(zhuǎn)移地址在寄存器中的CALL指令 CALL 16位寄存器 (SP)=(SP)-2 ((SS)*16+(SP))=IP (IP)=(16位寄存器) 轉(zhuǎn)移地址在內(nèi)存中的CALL指令 (1)CALL WORD PTR內(nèi)存單元地址 (2)CALL DWORD PTR內(nèi)存單元地址 MUL指令 (1)要么都是8位,要么都是16位,如果是8位,默認(rèn)放在AL中,另一個(gè)放在8位放在寄存器或內(nèi)存字節(jié)單元中;如果是16位,一個(gè)默認(rèn)在AX中,一個(gè)默認(rèn)放在16位寄存器或內(nèi)存字節(jié)單元中 (2)結(jié)果:如果是8位乘法,結(jié)果默認(rèn)放在AX中,如果是16位乘法,結(jié)果高位默認(rèn)在DX 中存放,低位在AX中存放。 格式: MUL REG MUL 內(nèi)存單元 內(nèi)存單元可以用不同的尋址方式給出 比如: MUL BYTE PTR ds:[0] 含義為: (AX)=(AL)*((DS)*16+0) MUL WORD PTR [BX+SI+8] 含義為: (AX)=(AX)*((DS)*16+(BX)+(SI)+8)結(jié)果的低16位 (DX)=(AX)*((DS)*16+(BX)+(SI)+8)結(jié)果的高16位 標(biāo)志寄存器: (1)用來存儲相關(guān)指令的某些執(zhí)行結(jié)果 (2)用來為CPU執(zhí)行相關(guān)指令提供行為依據(jù) (3)用來控制CPU的相關(guān)工作方式 簡稱flag,它是按位起作用的,每一位都有專門的含義,記錄特定的信息 Flag的1,3,5,12,13,14,15位在CPU中沒有使用,不具任何含義。而0,2,4,6,7,8,9,10,11位都具有特殊含義 ZF,零標(biāo)志位,它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為0,如果結(jié)果為0,那么ZF=1,如果結(jié)果不為0,那么ZF=0. 注意:在8086CPU的指令集中,有的指令的執(zhí)行影響標(biāo)志寄存器,比如:ADD,SUB,DIV,INC,OR,AND 等,它們大都是運(yùn)算指令(進(jìn)行邏輯或算術(shù)運(yùn)算);有的指令的執(zhí)行對標(biāo)志寄存器沒有影響,比如:MOV,PUSH,POP等,它們大都是傳送指令。 PF,奇偶標(biāo)志位,它記錄相關(guān)指令執(zhí)行后,其結(jié)果的所有二進(jìn)制位中1的個(gè)數(shù)是否為偶數(shù),如果1的個(gè)數(shù)為偶數(shù),PF=1,如果位奇數(shù),PF=0 SF,符號標(biāo)志位,它記錄相關(guān)指令執(zhí)行后,其結(jié)果是否為負(fù),如果為負(fù),SF=1,如果非負(fù),SF=0 SF,就是CPU對有符號數(shù)運(yùn)算結(jié)果的一種記錄,它記錄數(shù)據(jù)的正負(fù)。在我們將數(shù)據(jù)當(dāng)作有符號數(shù)來運(yùn)算的時(shí)候,可以通過它來得知結(jié)果的正負(fù)。如果我們將數(shù)據(jù)當(dāng)作無符號數(shù)來運(yùn)算,SF就的值則沒有意義 CF,進(jìn)位標(biāo)志位,在進(jìn)行無符號數(shù)運(yùn)算的時(shí)候,它記錄了運(yùn)算結(jié)果的最高有效位向更高的進(jìn)位值,或從更高位的借位值 對于位數(shù)為N的無符號數(shù)來說,其對應(yīng)的二進(jìn)制信息的最高位,既第N-1位,就是它的最高有效位, OF標(biāo)志位,OF記錄了有符號數(shù)運(yùn)算的結(jié)果是否發(fā)生了溢出,如果發(fā)生溢出,OF=1,如果沒有OF=0. 一定要注意OF和CF的區(qū)別:CF是對無符號數(shù)運(yùn)算有意義的標(biāo)志位,而OF是對有符號數(shù)運(yùn)算有意義的標(biāo)志位 ADC是帶進(jìn)位加法指令,它利用了CF上記錄的進(jìn)位值 格式:ADC操作對象 1,操作對象2 功能:操作對象1=操作對象1+操作對象2+CF SBB是帶借位減法指令,它利用了CF位上記錄的借位值 格式:SBB 操作對象1,操作對象2 功能:操作對象1=操作對象1-操作對象2-CF CMP比較指令,CMP的功能相當(dāng)于減法指令,只是不保存結(jié)果。CMP指令執(zhí)行后,將對標(biāo)志寄存器產(chǎn)生影響 格式:CMP 操作對象1,操作對象2 功能:計(jì)算操作對象1-操作對象2 但并不保存結(jié)果,僅僅根據(jù)計(jì)算結(jié)果對寄存器進(jìn)行設(shè)置 檢測比較結(jié)果的條件轉(zhuǎn)移指令 "轉(zhuǎn)移"指的是它能夠修改IP,而"條件"指的是它可以根據(jù)某種條件,決定是否修改IP 比如:JCXZ就是一個(gè)條件轉(zhuǎn)移指令,它可以檢測CX中的數(shù)值,如果(CX)=0,就修改IP, 否則什么也不做。所以條件轉(zhuǎn)移指令的轉(zhuǎn)移位移都是[-128,127] 大多數(shù)條件轉(zhuǎn)移指令都檢測寄存器的相關(guān)標(biāo)志位(CMP指令影響的那些,表示結(jié)果的標(biāo)志位),根據(jù)檢測的結(jié)果來決定是否修改IP,這些條件轉(zhuǎn)移指令通常都和CMP想配合使用,就好象CALL和RET指令通常相配合使用一樣 因?yàn)镃MP指令可以同時(shí)進(jìn)行兩種比較,無符號數(shù)比較和有符號數(shù)比較,所以CMP指令的比較結(jié)果進(jìn)行轉(zhuǎn)移的指令也分為兩種,既根據(jù)無符號數(shù)的比較結(jié)果進(jìn)行轉(zhuǎn)移的條件轉(zhuǎn)移指令,它們檢測ZF,CF的值;和根據(jù)有符號數(shù)的比較結(jié)果進(jìn)行轉(zhuǎn)移的條件轉(zhuǎn)移指令,它們檢測SF,OF,和ZF 的值 無符號數(shù)的比較結(jié)果進(jìn)行轉(zhuǎn)移的條件轉(zhuǎn)移指令 有符號數(shù)的比較結(jié)果進(jìn)行轉(zhuǎn)移的條件轉(zhuǎn)移指令的工作原理和無符號的相同,只是檢測了不同的標(biāo)志位。 DF標(biāo)志和串傳送指令 DF方向標(biāo)志位,在串處理指令中,控制每次操作后SI,DI的增減。 DF=0 每次操作后SI,DI遞增; DF=1 每次操作后SI,DI遞減; 串傳送指令 格式:MOVSB 功能:執(zhí)行MOVSB指令相當(dāng)于進(jìn)行下面幾步操作 (1)((ES)*16+(DI))=((DS)*16+(SI)) (2)如果DF=0,則:(SI)=(SI)+1 (DI)=(DI)+1 如果DF=1 則:(SI)=(SI)-1 (DI)=(DI)-1 MOVSB的功能是將DS:SI指向的內(nèi)存單元中的字節(jié)送入ES:DI中,然后根據(jù)標(biāo)志寄存器DF位的值,將SI和DI遞增或遞減 MOVSW的功能是將DS:SI指向的內(nèi)存單元中的WORD送入ES:DI中,然后根據(jù)標(biāo)志寄存器DF位的值,將SI和DI遞增2或遞減2 MOVSB和MOVSW進(jìn)行的是串傳送操作中的一個(gè)步驟,一般來說,MOVSB和MOVSW都和REP配合使用 REP MOVSB可以循環(huán)實(shí)現(xiàn)(CX)個(gè)字符的傳送 8086CPU提供下面兩條指令對DF位進(jìn)行設(shè)置 CLD指令:將標(biāo)志寄存器的DF位置0 STD指令:將標(biāo)志寄存器的DF位置1 PUSHF和POPF PUSHF功能是將標(biāo)志寄存器的值壓棧,POPF是從棧中彈出數(shù)據(jù),送入標(biāo)志寄存器中 內(nèi)中斷的產(chǎn)生 條件: (1)除法錯(cuò)誤,比如:DIV指令產(chǎn)生的除法溢出; (2)單步執(zhí)行; (3)執(zhí)行int0指令 (4)執(zhí)行int指令 CPU用8位的中斷類型碼通過中斷向量表(中斷向量的列表)找到相應(yīng)的中斷處理程序的入口地址。 所謂中斷向量,就是中斷處理程序的入口地址 中斷向量的表,就是中斷處理程序的入口地址的列表 中斷向量表在內(nèi)存中保存,其中存放著256個(gè)中斷源,所對應(yīng)的中斷處理程序的入口。 8086PC機(jī),中斷向量表指定放在內(nèi)存地址0處。從內(nèi)存0000:0000到0000:03E8的1000個(gè)單元中存放著中斷向量表。 中斷向量表中,一個(gè)表項(xiàng)存放一個(gè)中斷向量,也就是一個(gè)中斷處理程序的入口地址,對于8086CPU,這個(gè)入口地址包括段地址和偏移地址,所以一個(gè)表項(xiàng)占兩個(gè)字,高地址字存放段地址,低地址字存放偏移地址。 (1)(從中斷信息中)取得中斷類型碼 (2)標(biāo)志寄存器的值入棧;(因?yàn)樵谥袛噙^程中要改變標(biāo)志寄存器的值,所以先將其保存在棧中) (3)設(shè)置標(biāo)志寄存器的第8位TF和第9位IF的值為0; (4)CS的內(nèi)容入棧 (5)IP的內(nèi)容入棧 (6)從內(nèi)存地址為中斷類型碼*4和*4+2的兩個(gè)字單元中讀取中斷處理程序的入口地址設(shè)置IP和CS 簡單描述: (1)取的中斷類型碼N; (2)Pushf (3)TF=0,IF=0 (4)Push CS (5)PUSH IP (6)(IP)=(N*4),(CS)=(N*4+2) 中斷處理程序的編程方法: (1)保存用到的寄存器 (2)處理中斷 (3)恢復(fù)用到的寄存器 (4)用iRet指令返回 在中斷過程中,寄存器入棧的順序是標(biāo)志寄存器,CS,IP,而IRET的出棧順序是IP,CS,標(biāo)志寄存器,剛好和其相對應(yīng),實(shí)現(xiàn)了用執(zhí)行中斷處理程序前的CPU現(xiàn)場恢復(fù)標(biāo)志寄存器和CS,IP的工作 Int 指令:INT N 執(zhí)行過程: (1)取中斷類型碼 N (2)標(biāo)志寄存器入棧,IF=0;TF=0 (3)CS,IP入棧 (4)(IP)=(n*4),(CS)=(n*4+2) 系統(tǒng)將一些具有一定功能的子程序,以中斷處理程序的方式提供給應(yīng)用程序調(diào)用,當(dāng)然這些子程序也可以自己編寫. 在系統(tǒng)板的ROM中存放著一套程序,稱為BIOS(基本輸入輸出系統(tǒng)), BIOS主要包括: (1)硬件系統(tǒng)的檢測和初始化程序 (2)外部中斷和內(nèi)部中斷的中斷例程 (3)用于對硬件設(shè)備進(jìn)行I/O操作的中斷例程 (4)其他和硬件系統(tǒng)相關(guān)的中斷例程 BIOS和DOS提供的中斷例程安裝到內(nèi)存中: (1)開機(jī)后,CPU加電,初始化(CS)=0FFFFH,(IP)=0,自動(dòng)從FFFF:0單元開始執(zhí)行程序。FFFF:0處有一條轉(zhuǎn)跳指令,CPU執(zhí)行該指令后,轉(zhuǎn)去執(zhí)行BIOS中的硬件系統(tǒng)檢測和初始化程序 (2)初始化程序?qū)⒔IOS所支持的中斷向量,即將BIOS提供的中斷例程的入口地址登記在中斷向量表中。注意,對于BIOS所提供的中斷例程,只需要入口地址登記在中斷向量表中即可。因?yàn)樗鼈兪枪袒絉OM中的程序。一直在內(nèi)存中存在 (3)硬件系統(tǒng)檢測和初始化完成后,調(diào)用int 19h進(jìn)行操作系統(tǒng)的引導(dǎo),從此將計(jì)算機(jī)交有操作系統(tǒng)控制。 (4)DOS 啟動(dòng)后,除完成其他工作外,還將它所提供的中斷例程裝入內(nèi)存,并建立相應(yīng)的中斷向量。 在PC機(jī)系統(tǒng)中,和CPU通過總線相連的芯片除各種存儲器外,還有以下3種芯片: (1)各種接口卡(比如:網(wǎng)卡,顯卡)上的接口芯片,它們控制接口卡進(jìn)行工作 (2)主板上的接口芯片,CPU通過它們對部分外設(shè)進(jìn)行訪問 (3)其他芯片,用來存儲相關(guān)的系統(tǒng)信息,或進(jìn)行相關(guān)的輸入輸出處理 這些芯片中,都有一組可以由CPU讀寫的寄存器,這些寄存器,他們在物理上可能處于不同的芯片中,但是它們有以下兩點(diǎn)上相同: (1)都和CPU的總線相連,當(dāng)然這種連接是通過它們所在的芯片進(jìn)行的 (2)CPU對它們進(jìn)行讀或?qū)懙臅r(shí)候都通過控制線向它們所在的芯片發(fā)出端口讀寫命令。 可見,從CPU的角度,將這些寄存器都當(dāng)作端口,對它們進(jìn)行統(tǒng)一編址,從而建立了一個(gè)統(tǒng)一的端口地址空間。每個(gè)端口在地址空間中都有一個(gè)地址。 CPU可以直接讀寫3個(gè)地方的數(shù)據(jù): (1)CPU內(nèi)部的寄存器; (2)內(nèi)存單元 (3)端口 端口地址和內(nèi)存地址一樣,通過地址總線來傳送,在PC系統(tǒng)中,CPU最多可以定位64K個(gè)不同的端口。則端口地址的范圍是0-65535 端口的讀寫指令只有兩條:in和out 在in,out指令中,只能使用AX或AL來存放從端口中讀入的數(shù)據(jù)或要發(fā)送到端口中的數(shù)據(jù),訪問8位端口時(shí)用AL, 訪問16位端口時(shí)用AX 對0-255以內(nèi)的端口進(jìn)行讀寫時(shí) In al ,20h Out 20h,al 對256-65535的端口進(jìn)行讀寫時(shí),端口號放在DX中 Mov dx,3f8h In al,dx Out dx,al CMOS RAM PC機(jī)中,有一個(gè)CMOS RAM芯片,一般簡稱為CMOS。 (1)包含一個(gè)實(shí)時(shí)鐘和一個(gè)有128個(gè)存儲單元的RAM存儲器 (2)該芯片靠電池供電 (3)128個(gè)字節(jié)的RAM中,內(nèi)部實(shí)時(shí)鐘占用0-0dh單元來保存時(shí)間信息,其余大部分單元用于保存系統(tǒng)配置信息,供系統(tǒng)啟動(dòng)時(shí)BIOS程序讀取。BIOS也是提供了相關(guān)的程序,使我們可以在開機(jī)的時(shí)候配置CMOS RAM中的系統(tǒng)信息 (4)該芯片內(nèi)部有兩個(gè)端口,端口地址為70h和71h.CPU通過這兩端口在讀寫CMOS RAM (5)70h為地址端口,存放要訪問的CMOS RAM單元的地址;71H為數(shù)據(jù)端口,存放從選定的CMOS RAM單元中讀取數(shù)據(jù),或要寫入到其中的數(shù)據(jù)。可見,CPU對CMOS RAM的讀寫分兩步進(jìn)行,比如:讀CMOS RAM的2號單元: *將2送入端口70h *從71h讀出2號單元的內(nèi)容 Shl和shr 是邏輯依位指令,shl 是邏輯左移指令: (1)將一個(gè)寄存器或內(nèi)存單元中的數(shù)據(jù)向左移位; (2)將最后移出的一位寫入CF中 (3)最低位用0補(bǔ)充 如果移動(dòng)位數(shù)大于1時(shí),必須將移動(dòng)位數(shù)放在cl中 Shr 是邏輯右移指令,它和shl所進(jìn)行的操作剛好相反: (1)將一個(gè)寄存器或內(nèi)存單元中的數(shù)據(jù)想右移位; (2)將最后移出的一位寫入CF中 (3)最高位用0補(bǔ)充 如果移動(dòng)位數(shù)大于1時(shí),必須將移動(dòng)位數(shù)放在cl中 CPU除了有運(yùn)算能力 還要有I/O能力 外設(shè)接口芯片的內(nèi)部有若干寄存器,CPU將這些寄存器當(dāng)作端口來訪問 外設(shè)的輸入不直接送入內(nèi)存和CPU,而是送入相關(guān)的接口芯片的端口中;CPU向外設(shè)的輸出也不是直接送入外設(shè),而是先送入端口中,在由相關(guān)的芯片送到外設(shè)。CPU還可以向外設(shè)輸出控制命令,而這些控制命令也是先送到相關(guān)芯片的端口中,然后在由相關(guān)的芯片根據(jù)命令對外設(shè)實(shí)施控制。 PC機(jī)系統(tǒng)中,外中斷源一共有兩類: 1 可屏蔽中斷 2 不可屏蔽中斷 (8086CPU,不可屏蔽中斷類型碼固定為2) 鍵盤掃描碼被送入主板上的相關(guān)接口芯片的寄存器中,該寄存器的端口地址為60H 引發(fā)9號中斷 當(dāng)鍵盤的輸入到達(dá)60H端口時(shí),相關(guān)的芯片就會向CPU發(fā)出中斷類型碼為9的可屏蔽中斷信息。CPU檢測到該中斷信息后,如果IF=1, 則響應(yīng)中斷,引發(fā)中斷過程,轉(zhuǎn)去執(zhí)行int 9中斷例程 3執(zhí)行int9中斷例程 BIOS提供了int9中斷例程,用來進(jìn)行基本的鍵盤輸入處理: (1)讀出60H端口中的掃描碼; (2)如果是字符鍵的掃描碼,將該掃描碼和它對應(yīng)的字符碼(即ASCII碼)送入內(nèi)存中的BIOS鍵盤緩沖區(qū);如果是控制鍵(如CTRL)和切換鍵(如CapsLock)的掃描碼,則將其轉(zhuǎn)變?yōu)闋顟B(tài)字節(jié)(用二進(jìn)制位記錄控制鍵和切換鍵狀態(tài)的字節(jié))寫入內(nèi)存中的存儲狀態(tài)字節(jié)的單元 (3)對鍵盤系統(tǒng)進(jìn)行相關(guān)的控制,如:向芯片發(fā)出應(yīng)答信息 BIOS鍵盤緩沖區(qū)是系統(tǒng)啟動(dòng)后,BIOS用于存放int9中斷例程所接收的鍵盤輸入的內(nèi)存區(qū),該內(nèi)存區(qū)可以存儲15個(gè)鍵盤輸入,因?yàn)閕nt9中斷例程除了接收掃描碼外,還要產(chǎn)生和掃描碼對應(yīng)的字符碼,所以在BIOS鍵盤緩沖區(qū)中,一個(gè)鍵盤輸入用一個(gè)字單元存放,高位字節(jié)存放掃描碼,低位字節(jié)存放字符碼 鍵盤輸入的處理過程: (1)鍵盤產(chǎn)生掃描碼; (2)掃描碼送入60h端口; (3)引發(fā)9號中斷; (以上由硬件系統(tǒng)完成) (4)CPU執(zhí)行int9中斷例程處理鍵盤輸入 指令系統(tǒng)總結(jié): *數(shù)據(jù)傳送指令: 比如:MOV,PUSH,POP,PUSHF,POPF,XCHG等都是數(shù)據(jù)傳送指令,實(shí)現(xiàn)寄存器和內(nèi)存,寄存器和寄存器之間的單個(gè)數(shù)據(jù)傳送 *算術(shù)運(yùn)算指令 比如:ADD,SUB,ADC,SBB,INC,DEC,CMP,IMUL.IDIV,AAA等都是算術(shù)運(yùn)算指令,實(shí)現(xiàn)寄存器和內(nèi)存中的數(shù)據(jù)算數(shù)運(yùn)算,它們執(zhí)行結(jié)果影響標(biāo)志寄存器的:SF,ZF,CF,PF,AF位 *邏輯指令: 比如:AND,OR,NOT,XOR,TEST,SHL,SHR,SAL,SAR,ROL,ROR,RCL,RCR等,除了NOT指令外,它們都影響標(biāo)志寄存器相關(guān)標(biāo)志位 *轉(zhuǎn)移指令: 可以修改IP,或同時(shí)修改CS和IP的指令統(tǒng)稱為轉(zhuǎn)移指令,有以下幾類: (1)無條件轉(zhuǎn)移指令,比如:JMP (2)條件轉(zhuǎn)移指令,比如:JCXZ,JE,JB,JA,JNB,JNA (3)循環(huán)指令:LOOP (4)過程:CALL,RET,RETF (5)中斷:INT,IRET *處理機(jī)控制指令 : 這些指令對標(biāo)志寄存器或其他處理機(jī)狀態(tài)進(jìn)行設(shè)置,比如:CLD,STD,CLI,STI,NOP,CLC,CMC,STC,HLT,WAIT,ESC,LOCK等都是處理機(jī)控制指令 *串處理指令: 這些指令對內(nèi)存中的批量數(shù)據(jù)進(jìn)行處理:MOVSB,MOVSW,CMPS,SCAS,LODS,STOS等。若要使用這些指令方便地進(jìn)行批量數(shù)據(jù)的處理,則需要和REP,REPE,REPNE等前綴指令配合使用. BIOS提供了int 16h中斷例程。該中斷例程中包括的一個(gè)最重要的功能是從鍵盤緩沖區(qū)中讀取一個(gè)鍵盤輸入,該功能的編號為0,下面的指令從鍵盤緩沖區(qū)讀取一個(gè)鍵盤輸入,并且將其從緩沖區(qū)中刪除; MOV AH ,0 Int 16H 結(jié)果(AH)=掃描碼,(AL)=ASCII碼 INT 16H中斷例程的0號功能,步驟: (1)檢測鍵盤緩沖區(qū)中是否有數(shù)據(jù); (2)沒有則繼續(xù)做第一步 (3)讀取緩沖區(qū)第一個(gè)字單元中的鍵盤輸入 (4)將一讀取的鍵盤輸入從緩沖區(qū)中刪除 INT 9和INT 16相互配合。 應(yīng)用INT 13H中斷例程對磁盤進(jìn)行讀寫:(下面以3.5英寸軟盤為例) 現(xiàn)常用的3.5寸軟盤分為上下兩面,每面有80個(gè)磁道,每個(gè)磁道又分為18個(gè)扇區(qū),每個(gè)扇區(qū)的大小為512B。則:2面*80磁道*18扇區(qū)*512B=1440KB=1.44MB 磁盤的實(shí)際訪問由磁盤控制器進(jìn)行,只能以扇區(qū)為單位對磁盤進(jìn)行讀寫,在讀扇區(qū)的時(shí)候,要給出 面號,磁道號和扇區(qū)號。面號和磁道號從0開始,而扇區(qū)從1開始。 我們可通過調(diào)用BIOS中斷例程(INT 13H)來訪問磁盤 下面讀取0面0道1扇區(qū)的內(nèi)容到0:200 MOV AX,0 MOV ES,AX MOV BX,200H ;指向接收從扇區(qū)讀入數(shù)據(jù)的內(nèi)存 MOV AL,1 ;讀取的扇區(qū) MOV CH,0 ;磁道號 MOV CL,1;扇區(qū)號 MOV DL,0;驅(qū)動(dòng)器號 軟盤從0開始,0:軟盤A,1:軟盤B 硬盤從80H開始,80H硬盤C.81H:硬盤D MOV DH,0 ;磁頭號 (對于軟盤即面號,因?yàn)橐粋€(gè)面用一個(gè)磁頭來讀寫) MOV AH,2 ;(AH)=INT 13H的功能號(2表示讀扇區(qū)) INT 13H 返回參數(shù): 操作成功:(AH)=0,(AL)=讀入的扇區(qū)數(shù) 操作失?。?AH)=出錯(cuò)代碼 將0:200中的內(nèi)容寫入0面0道1扇區(qū) MOV AX,0 MOV ES,AX MOV BX,200H MOV AL ,1 ;寫入的扇區(qū)數(shù) MOV CH,0 ;磁道號 MOV CL,1;扇區(qū)號 MOV DL,0; ;驅(qū)動(dòng)器號 MOV DH,0;磁頭號(面) MOV AH,3 ;INT 13H 功能號(3表示寫扇區(qū)) INT 13H 邏輯扇區(qū)號和物理扇區(qū)號的關(guān)系如下: 邏輯扇區(qū)號=(面號*80+磁道號)*18+扇區(qū)號-1 根據(jù)邏輯扇區(qū)號算出物理編號: INT():取商; REM():取余數(shù). 面號=INT(邏輯扇區(qū)號/(1440)) 磁道號=INT((REM(邏輯扇區(qū)號/1440))/18) 扇區(qū)號=REM((REM(邏輯扇區(qū)號/1440))/18)+1 (摘抄)任何合理的學(xué)習(xí)過程(盡可能排除走彎路,盲目探索,不成系統(tǒng))都是一個(gè)循序漸進(jìn)的過程,我們必須通過易于全面把握的事物,來學(xué)習(xí)和探索一般的規(guī)律和方法。 信息技術(shù)是一個(gè)發(fā)展非??欤招略庐惖募夹g(shù),新的東西不斷出現(xiàn),使人在學(xué)習(xí)的時(shí)候往往無所適從,在你的身邊不斷有這樣的故事出現(xiàn):COOL先生用三天就學(xué)會了某中語言,并開始用它的編的軟件,在這個(gè)故事的感召下,我們初學(xué)者也去嘗試,但完全是另一種結(jié)果,COOL先生的快速學(xué)習(xí)只是露出水面的冰山一角,深藏水下的是他的較為系統(tǒng)的相關(guān)基礎(chǔ)知識和相關(guān)的技術(shù)....... 補(bǔ)碼(8位數(shù)據(jù)為例):先確定用00000000b-01111111b表示0-127,然后再用它們安位取反加1后的數(shù)據(jù)表示負(fù)數(shù). 8位補(bǔ)碼表示的范圍:-128-127 [1]前轉(zhuǎn)移 編譯器中有一個(gè)地址計(jì)數(shù)器(AC),編譯器在編譯程序過程中,每讀到一個(gè)字節(jié)AC就加一。當(dāng)編譯器遇到一些偽操作的時(shí)候,也會根據(jù)具體情況使AC增加,如DB,DW等 在向前轉(zhuǎn)移時(shí),編譯器可以在讀到標(biāo)號S后記下AC的值A(chǔ)S,在讀到JMP ...S后記下AC的值A(chǔ)J,編譯器可以用AS-AJ算出位移量DISP JMP SHORT S所對應(yīng)的機(jī)器碼格式為:EB DISP(占兩個(gè)字節(jié)) JMP NEAR PTR S所對應(yīng)的機(jī)器碼格式為: E9 DISP(占3個(gè)字節(jié)) JMP FAR PTR S所對應(yīng)的機(jī)器碼格式為:EA 偏移地址:段地址(占5個(gè)字節(jié)) [2]后轉(zhuǎn)移 編譯器先讀到JMP...S指令,由于它還沒讀到標(biāo)號S,所以編譯器此時(shí)還不能確定標(biāo)號S 處的AC值,也就是說,編譯器不能確定位移量DISP的大小,此時(shí),編譯器將JMP...S指令都當(dāng)作JMP SHORT S來讀取,記下JMP..S指令的位置和AC的值A(chǔ)J,并作如下處理: 對于JMP SHORT S,編譯器生成EB和1個(gè)NOP指令(相當(dāng)于預(yù)留1個(gè)字節(jié)的空間,存放8位DISP) 對于JMP S和JMP NEAR PTR S,編譯器生成EB和兩個(gè)NOP指令(相當(dāng)于預(yù)留2個(gè)字節(jié)的空間,存放16位DISP) 對于JMP FAR PTR S編譯器生成 EB和4個(gè)NOP指令(相當(dāng)于預(yù)留4個(gè)字節(jié)的空間,存放段地址和偏移地址) 以上處理后,編譯器繼續(xù)工作,當(dāng)向后讀到標(biāo)號S時(shí),記下AC的值A(chǔ)S,并計(jì)算出轉(zhuǎn)移的位移量:DISP=AS-AJ.(END) 本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/mmzsyx/archive/2008/12/07/3465038.aspx |
|