青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

luqingfei@C++

為中華之崛起而崛起!
兼聽則明,偏聽則暗。

Win32匯編--需要了解的基礎知識

在一個月前我打算學Win32匯編,發(fā)現(xiàn)匯編的基礎不是太好,便花了近一個月的時間把王爽老師的《匯編語言》看了一遍。現(xiàn)在再來看Win32匯編,比一個月前輕松了不少。真是本看書,對于我個人來說。

接下來,我將繼續(xù)Win32匯編的學習。堅持、堅持!

Let's go!

 

Background

 

Windows環(huán)境下32位匯編語言是一種全新的編程語言。它使用與C++語言相同的API接口,不僅可以用來開發(fā)出大型的軟件,而且是了解操作系統(tǒng)運行細節(jié)的最佳方式。

 

Win32指的是32位的Windows系列操作系統(tǒng)。

 

19905月份微軟推出了Windows 3.0,可以支持Intel 80286/386/486微處理器的保護模式,并可以訪問達16MB的內(nèi)存。Windows 3.0一面世便在商業(yè)上取得了驚人的成功,從而一舉奠定了Microsoft在操作系統(tǒng)上的壟斷地位。

 

19924月,Microsoft推出了更穩(wěn)定的Windows 3.1,可以支持True Type字體。Windows 3.116Windows中最流行的版本。

 

19935月,Microsoft發(fā)布了具備安全性和穩(wěn)定性特征的32位操作系統(tǒng)Windows NT 3.11,主要針對網(wǎng)絡和服務器市場。NT代表新技術(New Technology)。NT 3.11Windows系列中使用32位編程模式的第一個版本。它充分利用80386及以上處理器的平面地址空間和保護模式等新技術。

 

19958月,Microsoft推出新一代操作系統(tǒng)Windows 95Windows 95實現(xiàn)了很友好的用戶界面,支持即插即用功能,支持主流多媒體設備和DirectX編程接口,成為Microsoft發(fā)展史上的一個里程碑,也是操作系統(tǒng)發(fā)展史上的一個里程碑。從此,Windows 9x便取代了Windows 3.xMS-DOS操作系統(tǒng),成為個人計算機平臺的主流操作系統(tǒng)。

 

1998Microsoft又發(fā)布了使用更方便的Windows 98

 

在操作系統(tǒng)的分類上,Microsoft根據(jù)家庭個人用戶和商業(yè)辦公用戶的不同需求,分別提供Windows 9xWindows NT系列,Windows 9x注重用戶界面及其他易用性特征,而NT系列則在純32位內(nèi)核的穩(wěn)定性和可靠性等企業(yè)級特征上下功夫。

 

2000年,微軟發(fā)布采用純32位內(nèi)核并照顧了家庭消費類應用軟件的Windows NT 5.0,即Windows 2000。至此Micosoft的兩個系列操作系統(tǒng)(9xNT)終于開始統(tǒng)一。

 

為了利用MS-DOS時代大量的應用程序,保持向下的兼容性,Windows 9x的內(nèi)核模塊還有許多地址使用16位程序,但在編程上,支持32位的編程模式。

 

Windows NT系列和Windows 9x系列操作系統(tǒng)都支持Win32 APIApplication Programming Interface),即Windows 32位應用程序編程接口,Win32 API為應用程序提供了大量的系統(tǒng)功能調(diào)用,通過Win32 API調(diào)用Windows系統(tǒng)相當于在MS-DOS中通過中斷方式調(diào)用系統(tǒng)功能。就像DOS匯編程序中隨處可見的 INT 21h指令一樣,Windows應用程序中Win32 API也隨處可見。

 

Windows的特色

對于使用者來說:

1)圖形用戶界面;(GUIGraphic User Interface Windows最重要的特色。

2)一致的用戶界面; 便于使用。

3)多任務。 非常重要的特色。用戶可以同時運行多個程序,可以在不同的程序之間傳送數(shù)據(jù)。

 

對于程序員來說,更關心隱藏在底下的東西:

1大量的函數(shù)調(diào)用Win32支持上千種函數(shù)的調(diào)用,幾乎涉及所有的方面,程序員可以把更多的時間放在程序的邏輯結構和用戶界面上。

2和設備的無關性Win32程序并不直接訪問屏幕、打印機和鍵盤等硬件設備,Windows虛擬了所有的硬件。只要有硬件的設備驅動程序,這個硬件就可以使用,應用程序并不需要關心硬件的具體型號。與DOS編程中需要針對不同的顯示卡和打印機等編寫很多的驅動程序來比,這個特性對程序員的幫助是巨大的。

3內(nèi)存管理。由于內(nèi)存分頁和虛擬內(nèi)存的使用,每個程序都可以使用4GB的地址空間,DOS編程時必須考慮的640KB的內(nèi)存問題已經(jīng)成為歷史。

 

 

必須了解的東西

 

80x86處理器的工作模式

 

80386處理器有3種工作模式:實模式、保護模式和虛擬86模式。

實模式和虛擬86模式是為了和8086處理器兼容而設置的。在實模式下,80386處理器就相當于一個快速的8086處理器。

保護模式是80386處理器的主要工作模式。在此方式下,80386可以尋址4GB的地址空間,同時,保護模式提供了80386先進的多任務、內(nèi)存分頁管理和優(yōu)先級保護等機制。

 

為了在保護模式下繼續(xù)提供和8086處理器的兼容,80386又設計了一種虛擬86模式,以便可以在保護模式的多任務條件下,有的任務運行32位程序,有的任務運行MS-DOS程序。

在虛擬86模式下,同樣支持任務切換、內(nèi)存分頁管理和優(yōu)先級,但內(nèi)存的尋地址方式和8086相同,也是可以尋址1MB的空間。

 

 

實模式是80386處理器工作的基礎,這時80386當做一個快速的8086處理器工作。在實模式下可以通過指令切換到保護模式,也可以從保護模式退回實模式。

虛擬86模式則以保護模式為基礎,在保護模式和虛擬86模式之間可以互相切換,但不能從實模式直接進入虛擬86模式或從虛擬86模式直接退到實模式。

 

 

實模式

80386處理器被復位或加電的時候以實模式啟動。這時候處理器中的各寄存器以實模式的初始化值工作。80386處理器在實模式下的存儲器尋址方式和8086是一樣的,由段寄存器的內(nèi)容乘以16當做基地址,加上段內(nèi)的偏移地址形成最終的物理地址,這時候它的32位地址線只使用了低20位。在實模式下,80386處理器不能對內(nèi)存進行分頁管理,所以指令尋址的地址就是內(nèi)存中實際的物理地址。在實模式下,所有的段都是可以讀、寫和執(zhí)行的。

 

實模式下80386不支持優(yōu)先級,所有的指令相當于在工作在特權級(優(yōu)先級0),所以它可以執(zhí)行所有特權指令,包括讀寫控制寄存器CR0等。實際上,80386就是通過在實模式下初始化控制寄存器,GDTRLDTRIDTRTR等管理寄存器以及頁表,然后再通過加載CR0使其中的保護模式使能位置位而進入保護模式的。實模式下不支持硬件上的多任務切換。

 

實模式下的中斷處理方式和8086處理器相同,也用中斷向量表來定位中斷服務程序地址。中斷向量表的結構也和8086處理器一樣,每4個字節(jié)組成一個中斷向量,其中包括兩個字節(jié)的段地址和兩個字節(jié)的偏移地址。

 

從編程的角度看,除了可以訪問80386新增的一些寄存器外,實模式的80386處理器相比8086,其最大的好處是可以使用8038632位寄存器,用32位寄存器進行編程可以使計算程序更加簡捷,加快了執(zhí)行速度。其次,80386中增加的兩個輔助段寄存器FSGS在實模式下也可以使用,這樣,同時可以訪問的段達到了6個而不必考慮重新裝入的問題;最后,很多80386的新增指令也使一些原來不很方便的操作得以簡化,如80386中可以使用下述指令進行數(shù)組訪問:

       mov cx,[eax + ebx * 2 + 數(shù)組基地址]

       這相當于把數(shù)組下標為eaxebx的項目放入cx中;ebx*2中的2可以是1,2,48,這樣就可以支持8位到64位的數(shù)組。

另外,pushadpopad指令可以一次把所有8個通用寄存器的值壓入或從堆棧中彈出,比起用下面的指令分別將8個寄存器入棧要快了很多:

       push eax

       push ebx

      

       pop ebx

       pop eax

 

當然,使用了這些新指令的程序是無法拿回到8086處理器上去執(zhí)行的,因為這些指令的編碼在8086處理器上是未定義的。

 

 

保護模式

80386工作在保護模式下的時候,它的所有功能都是可用的。這時80386所有的32根地址線都可供尋址,物理尋地址空間高達4GB。在保護模式下,支持內(nèi)存分頁機制,提供了對虛擬內(nèi)存的良好支持。雖然與8086可尋址的1MB物理地址空間相比,80386可尋地址的物理地址空間可謂很大,但實際的微機系統(tǒng)不可能安裝如此大的物理內(nèi)存。所以,為了運行大型程序和真正實現(xiàn)多任務,虛擬內(nèi)存是一種必需的技術。

 

保護模式下80386支持多任務,可以依靠硬件僅在一條指令中實現(xiàn)任務切換。任務環(huán)境的保護工作是由處理器自動完成的。在保護模式下,80386處理器還支持優(yōu)先級機制,不同的程序可以運行在不同的優(yōu)先級上。優(yōu)先級一共分0~3 四個級別,操作系統(tǒng)運行在最高的優(yōu)先級0上,應用程序則運行在比較低的級別上;配合良好的檢查機制后,既可以在任務間實現(xiàn)數(shù)據(jù)的安全共享也可以很好地隔離各個任務。從實模式切換到保護模式是通過修改控制寄存器CR0的控制位PE(位0)來實現(xiàn)的。在這之前還需要建立保護模式必需的一些數(shù)據(jù)表,如全局描述符表GDT和中斷描述符表IDT等。

 

DOS操作系統(tǒng)運行于實模式下,而Windows操作系統(tǒng)運行于保護模式下。

 

 

虛擬86模式

虛擬86模式是為了在保護模式下執(zhí)行8086程序而設置的。雖然80386處理器已經(jīng)提供了實模式來兼容8086程序,但這時8086程序實際上只是運行得快了一點,對CPU的資源還是獨占的。在保護模式的多任務環(huán)境下運行這些程序時,它們中的很多指令和保護模式環(huán)境格格不入,如段尋址方式、對中斷的處理和I/O操作的特權問題等。為了在保護模式下工作而丟棄這些程序的代價是巨大的。設想一下,如果Windows80386處理器推出的時候宣布不能運行以前的MS-DOS程序,那么就等于放棄了一個巨大的軟件庫,Windows以及80386處理器可能就會落得和蘋果機一樣的下場,這是MicrosoftIntel都不愿意看到的。所以,80386處理器又設計了一個虛擬86模式。

 

虛擬86模式是以任務形式在保護模式上執(zhí)行的,在80386上可以同時支持由多個真正的80386任務和虛擬86模式構成的任務。在虛擬86模式下,80386支持任務切換和內(nèi)存分頁。在Windows操作系統(tǒng)中,有一部分程序專門用來管理虛擬86模式的任務,稱為虛擬86管理程序。

 

既然虛擬86模式以保護模式為基礎,它的工作方式實際上是實模式和保護模式的混合。為了和8086程序的尋地址方式兼容,虛擬86模式采用和8086一樣的尋址方式,即用段寄存器乘以16當作基址再配合偏移地址形成線性地址,尋址空間為1MB。但顯然多個虛擬86任務不能同時使用同一位置的1MB地址空間,否則會引起沖突。操作系統(tǒng)利用分頁機制將不同虛擬86任務的地址空間映射到不同的物理地址上去,這樣每個虛擬86任務看起來都認為自己在使用0~1MB的地址空間。

 

8086代碼中有相當一部分指令在保護模式下屬于特權指令,如屏幕中斷的cli和中斷返回指令iret等。這些指令在8086程序中是合法的。如果不讓這些指令執(zhí)行,8086代碼就無法工作。為了解決這個問題,虛擬86管理程序采用模擬的方法完成這些指令。這些特權指令執(zhí)行的時候引起了保護異常。虛擬86管理程序在異常處理程序中檢查產(chǎn)生異常的指令,如果是中斷指令,則從虛擬86任務的中斷向量表中取出中斷處理程序的入口地址,并將控制轉移過去;如果是危及操作系統(tǒng)的指令,如cli等,則簡單地忽略這些指令,在異常處理程序返回的時候直接返回到下一條指令。通過這些措施,8086程序既可以正常地運行下去,在執(zhí)行這些指令的時候又覺察不到已經(jīng)被虛擬86管理程序做了手腳。MS-DOS應用程序在Windows操作系統(tǒng)中就是這樣工作的。

 

 

Windows的內(nèi)存管理

Win32匯編中,每個程序都可以用4GB的內(nèi)存嗎?

Win32匯編源代碼中為什么看不到CSDSESSS等段寄存器的使用?

 

DOS操作系統(tǒng)的內(nèi)存安排

Win32編程相對于DOS編程最大的區(qū)別之一就是內(nèi)存的使用。

00000h

中斷向量表

00400h

BIOS數(shù)據(jù)區(qū)

00500h

DOS數(shù)據(jù)區(qū)

 

系統(tǒng)程序

DOS的駐留部分、驅動程序等)

 

可用空間

A0000h

圖形模式視頻緩沖區(qū)

B0000h

單色字符模式視頻緩沖區(qū)

B8000h

彩色字符模式視頻緩沖區(qū)

C0000h

VGA BIOS地址

C8000h

ROM擴展、系統(tǒng)BIOS地址

FFFFFh

64KB高端內(nèi)存

 

 

在實模式下,一個內(nèi)存尋址方式是,一個完整的地址由段地址和偏移地址兩部分組成。段地址放在16位的段寄存器中,然后在指令中用16位的偏移地址尋址。處理器換算時先將段地址乘以10h(即16),得到段在物理內(nèi)存中的起始地址;然后 加上16位的偏移地址得到實際的物理地址。

 

80386處理器工作在保護模式和虛擬8086模式的時候,可以使用全部32根地址線訪問內(nèi)存4GB大的內(nèi)存。段地址加偏移地址的計算方法顯然無法覆蓋這么大的范圍。但計算一下就可以發(fā)現(xiàn),實際上和8086同樣的限制已經(jīng)不復存在,因為80386所有的通用寄存器都是32位的,232次方相當于4G,所以用任何一個通用寄存器來間接尋址,不必分段就已經(jīng)可以訪問到所有的內(nèi)存地址。

 

這是不是說,在保護模式下,段寄存器就不再有用了呢?答案是否定的。實際上段寄存器更有用了,雖然在尋址上不再有分段的限制問題,但在保護模式下,一個地址空間是否可以被寫入,可以被多少優(yōu)先級的代碼寫入,是不是允許執(zhí)行等涉及保護的問題就出來了。要解決這些問題,必須對一個地址空間定義一些安全上的屬性。段寄存器這時就派上了用途。但是涉及屬性和保護模式下段的其他參數(shù),要表示的信息太多了,要用64位長的數(shù)據(jù)才能表示。我們把這64位的屬性數(shù)據(jù)叫做段描述符(Segment Desciptor)。

 

80386的段寄存是16位的,無法放下保護模式下64位的段描述符。解決辦法是把所有段的段描述符順序放在內(nèi)存中的指定位置,組成一個段描述符表(Descriptor Table);而段寄存器中的16位用來做索引信息,指定這個段的屬性用段描述符表中的第幾個描述符來表示。這時,段寄存器中的信息不再是段地址了,而是段選擇器(Segment Selector)。可以通過它在段描述符表中,選擇一個項目以得到段的全部信息。

 

既然這樣,段描述符表放在哪里呢?80386中引入了兩個新的寄存器來管理段描述符表。一個是48位的全局描述符表寄存器GDTRGlobal Descriptor Table Register),一個是16位的局部描述符表寄存器LDTRLocal Descriptor Table Register)。那么,為什么有兩個描述符表寄存器呢?

 

GDTR指向的描述符表為全局描述符表GDTGlobal Descriptor Table)。它包含系統(tǒng)中所有任務都可用的段描述符,通常包含描述操作系統(tǒng)所使用的代碼段、數(shù)據(jù)段和堆棧段的描述符及各任務的LDT段等;全局描述符表只有一個。

 

LDTR則指向局部描述符表LDTLocal Descriptor Table)。80386處理器設計成每個任務都有一個獨立的LDT。它包含有每個任務私有的代碼段、數(shù)據(jù)段和堆棧段的描述符,也包含該任務所使用的一些門描述符,如任務門和調(diào)用門描述符等。

 

不同任務的局部描述符表分別組成不同的內(nèi)存段,描述這些內(nèi)存段的描述符當做系統(tǒng)描述符放在全局描述符表中。和GDTR直接指向內(nèi)存地址不同,LDTRCSDS等段選擇器一樣只存放索引值,指向局部描述符表內(nèi)存段對應的描述符在全局描述符表中的位置。隨著任務的切換,只要改變LDTR的值,系統(tǒng)當前的局部描述符表LDT也隨之切換,這樣便于各任務之間數(shù)據(jù)的隔離。但GDT并不隨著任務的切換而切換。

 

看到這里,讀者可能會提出一個問題,既然有全局描述符表和局部描述符表兩個表,那么段選擇器中的索引值對應哪個表中的描述符呢?實際上,16位的段選擇器中只有高13位表示索引值。剩下的3個數(shù)據(jù)位中,第01位表示程序的當前優(yōu)先RPL;第2TI位用來表示在段描述符的位置;TI=0表示在GDT中,TI=1表示在LDT中。

 

 

80386的內(nèi)存分頁機制

在實模式下尋址的時候,段寄存器+偏移地址經(jīng)過轉換計算以后得到的地址是物理地址,也就是在物理內(nèi)存中的實際地址。

而保護模式下,段選擇器+偏移地址轉換后的地址被稱為線性地址,而不是物理地址。

 

線性地址是物理地址嗎?

可能是,也可能不是,這取決于80386的內(nèi)存分頁機制是否被使用。

在單任務的DOS系統(tǒng)中,一個應用程序可以使用所有的空閑內(nèi)存。程序退出后,操作系統(tǒng)回收所有的碎片內(nèi)存并且合并成一個大塊內(nèi)存繼續(xù)供下一個程序使用。內(nèi)存合并過程中的一個極端情況匯報系統(tǒng)中有多個TSR卸載后,后裝入的TSR會留存內(nèi)存的中間部位,把空閑內(nèi)存隔成兩個區(qū)域。這時應用程序使用的最大內(nèi)存塊只能是這兩塊內(nèi)存中較大的一塊,無法將它們合并使用。

 

對于一個多任務的操作系統(tǒng),內(nèi)存的碎片化是不能容忍的。否則,經(jīng)過一段時間后,即使空閑內(nèi)存的總和很大,也可能出現(xiàn)任何一處內(nèi)存都小到無法裝入執(zhí)行程序的地步。所以多任務操作系統(tǒng)中碎片內(nèi)存的合并是個很重要的問題。

 

80386處理器的分頁機制可以很好地解決這個問題。80386處理器把4KB大小的一塊內(nèi)存當做一頁內(nèi)存,每頁物理內(nèi)存可以根據(jù)頁目錄和頁表,隨意映射到不同的線性地址上。這樣,就可以將物理地址不連續(xù)的內(nèi)存的映射連到一起,在線性地址上視為連續(xù)。在80386處理器中,除了和CR3寄存器(指定當前頁目錄的地址)相關的指令使用的是物理地址外,其他所有指令都是用線性地址尋址的。

 

是否啟用內(nèi)存分頁機制是由80386處理器新增的CR0寄存器中的位31PG位)決定的。如果PG=0,則分頁機制不啟用,這時所有指令尋址的地址(線性地址)就是系統(tǒng)中實際的物理地址;當PG=1的時候,80386處理器進入內(nèi)存分頁管理模式,所有的線性地址要經(jīng)過頁表的映射才得到最后的物理地址。

 

內(nèi)存分頁管理只能在保護模式下才可以實現(xiàn),實模式不支持分頁機制。但不管在哪種模式下,所有尋址指令使用的都是線性地址,程序不用關心數(shù)據(jù)最后究竟存放在物理內(nèi)存的哪個地方。

 

頁表規(guī)定的不僅是地址的映射,同時還規(guī)定了頁的訪問屬性,如是否可寫、可讀和可執(zhí)行等。比如把代碼所在的內(nèi)存頁設置為可讀與可執(zhí)行,那么權限不夠的代碼向它寫數(shù)據(jù)就會引發(fā)保護異常。利用這個機制可以在硬件層次上支持虛擬內(nèi)存的實現(xiàn)。

 

頁表可以指定一個頁面并不真正映射到物理內(nèi)存中,這樣,訪問這個頁的指令會引發(fā)頁異常錯誤。這時,處理器會自動轉移到頁異常處理程序中去,操作系統(tǒng)可以在異常處理程序中將硬盤上的虛擬內(nèi)存讀到內(nèi)存中并修改頁表重新映射,然后重新執(zhí)行引發(fā)異常的指令。這樣指令可以正常執(zhí)行下去。

 

 

Windows的內(nèi)存安排

Windows系統(tǒng)一般在硬盤上建立大小為物理內(nèi)存兩倍左右的交換文件(文件名在Windows 9x下為Win386.swpWindows NT下為PageFile.sys)用做虛擬內(nèi)存。

利用80386處理器的內(nèi)存分頁機制,交換文件在尋地址上可以很方便地作為物理內(nèi)存使用。只需在真正訪問到的時候將硬盤文件的內(nèi)容讀入物理內(nèi)存,然后重新將線性地址映射到這塊物理內(nèi)存就可以了。同樣道理,被執(zhí)行的可執(zhí)行文件也不必真正裝入內(nèi)存,只要在頁表中建立映射關系,以后到真正訪問到的時候再調(diào)入物理內(nèi)存。

 

如果把虛擬內(nèi)存暫時先視為物理內(nèi)存的一部分,從物理內(nèi)存中的層次看,Windows操作系統(tǒng)和DOS一樣,也是所有的內(nèi)容共享內(nèi)存,如操作系統(tǒng)使用的代碼和數(shù)據(jù)(GDTLDT與頁表等),當前執(zhí)行中的所有程序的代碼和數(shù)據(jù)以及這些程序調(diào)用的DLL的代碼和數(shù)據(jù)等。

 

但是從應用程序代碼的層次看,也就是說從分頁映射后線性地址層次看,內(nèi)存的安排卻不是這個樣子。因為Windows是一個分時的多任務操作系統(tǒng),CPU時間被分成一個個的時間片后分配給不同程序輪流使用,在一個程序的時間片中,和這個程序執(zhí)行無關的東西(如其他程序的代碼和數(shù)據(jù))并不需要映射到線地址中去。

 

Windows操作系統(tǒng)通過切換不同的頁表內(nèi)容讓線性地址在不同的時間片中映射不同的內(nèi)容。在物理內(nèi)存中,操作系統(tǒng)和系統(tǒng)DLL的代碼需要供每個應用程序調(diào)用,所以在所有的時間片中都必須被映射;用戶程序只在自己所屬的時間片內(nèi)被映射;而用戶DLL則有選擇地被映射。

 

 

Win32編程中幾個很重要的概念:

每個應用程序都有自己的4GB的尋址空間。該空間可存放操作系統(tǒng)、系統(tǒng)DLL和用戶DLL的代碼,它們之中有各種函數(shù)供應用程序調(diào)用。再除去其他的一些空間,余下的是應用程序的代碼、數(shù)據(jù)和可以分配的地址空間。

 

不同應用程序的線性地址空間是隔離的。雖然它們在物理內(nèi)存中同時存在,但在某個程序所屬的時間片中,其他應用程序程序的代碼和數(shù)據(jù)沒有被映射到可尋地址的線性地址中,所以是不可訪問的。從編程的角度看,程序可以使用4GB的尋址空間,而這個空間是私有的。

 

DLL程序沒有自己的私有的空間。它們總是被映射到其他應用程序的地址空間中,當做和其他應用程序的一部分運行。原因很簡單,如果它不和其他程序同屬一個地址空間,應用程序該如何調(diào)用它呢?

 

Win32匯編的角度看內(nèi)存尋址

DOS下的分段尋地址方式令人一頭霧水,80386保護模式的內(nèi)存管理就更復雜。

 

Windows是一個多任務操作系統(tǒng),最首要的宗旨就是穩(wěn)定壓倒一切,如果描述符表以及頁表等內(nèi)容交給用戶程序是很不安全的,不用說全局描述符表,就是為每個程序建立的局部描述符表也不應該讓用戶程序改寫,否則用戶可以通過構造自己的描述符來訪問操作系統(tǒng)不希望用戶訪問的東西。任何權限上開放引發(fā)的安全問題都是很嚴重的。

病毒程序就是利用這些系統(tǒng)漏洞,提升自身的權限,做一些破壞動作的。

 

所以,Windows操作系統(tǒng)干脆為用戶程序安排好了一切。具體表現(xiàn)在為用戶程序的代碼段、數(shù)據(jù)段和堆棧段全部預定義好了段描述符。這些段的起始地址為0,限長為ffffffff,所以用它們可以直接尋址全部的4GB地址空間。程序開始執(zhí)行的時候,CSDSESSS都已經(jīng)指向了正確的描述符,在整個程序的生命周期內(nèi),程序員不必改動這些段寄存器,也不必關心它們的值究竟是多少(實際上,想改也改不了)。

 

所以對Win32匯編程序來說,整個源程序中竟然可以不用出現(xiàn)段寄存器的身影。這在DOS匯編編程中是不可想象的。

 

并不是Win32匯編源代碼用不到段寄存器,而是用戶在使用中不必去關心段寄存器。

 

 

Windows的特權保護

Windows的特權保護和處理器硬件的支持是分不開的。

優(yōu)先級的劃分、指令的權限檢查和超出權限訪問的異常處理等是構成特權保護的基礎。

1Win32匯編中為什么找不到中斷指令的使用?

2Windows錯誤的藍屏屏幕是從哪里來的?

 

80386的中斷和異常

中斷指當程序執(zhí)行過程中有更重要的事情需要實時處理時(如串口中有數(shù)據(jù)到達,不及時處理數(shù)據(jù)會丟失,串行控制器就提交一個中斷信號給處理器要求處理),硬件通過中斷控制器通知處理器。處理器暫時掛起當前運行的程序,轉移到中斷處理程序中;當中斷處理程序處理完畢后,通過iret指令回到原先被打斷的程序中繼續(xù)執(zhí)行。

 

異常指指令執(zhí)行中發(fā)生不可忽略的錯誤時(如遇到無效的指令編碼,除法指令除零等),處理器用和中斷處理相同的操作方法掛起當前運行的程序轉移到異常處理程序中。異常處理程序決定在修正錯誤后是否回到原來的地方繼續(xù)執(zhí)行。

 

更為DOS匯編程序員熟悉的中斷,指的是用int n指令直接轉移到中斷向量n指定的中斷處理程序中執(zhí)行。嚴格地講,int n指令應該算自陷而不是中斷。因為這時并不是程序被急需解決的事情打斷。而是自己要求停止執(zhí)行并轉移到中斷處理程序中去。

 

不管中斷、異常還是自陷,雖然它們產(chǎn)生的原因不同,但處理過程是類似的,都通過中斷向量表里存放的入口地址轉移到服務程序,都由CPU自動在堆棧中保護斷點地址,最后也都可以用iret指令返回指令被中斷的地方。

 

808680386實模式下中斷和異常的處理過程。

中斷和異常服務程序地址存放在中斷向量表中。中斷向量表位于物理內(nèi)存00000h開始的400h字節(jié)中,共支持100h個中斷向量;每個中斷向量是一個xxxx:yyyy格式的地址,占用4字節(jié)。當發(fā)生n號異常或n號中斷,或者執(zhí)行到int n指令的時候,CPU首先到內(nèi)存n 4的地方取出服務程序的地址aaaa:bbbb;然后將標志寄存器、中斷時的CSIP壓入堆棧,接著轉移到aaaa:bbbb處執(zhí)行;在服務程序最后遇到iret的時候,CPU從堆棧中標志寄存器,然后取出CSIP并返回。

 

在保護模式下,中斷或異常處理往往從用戶代碼切換到操作系統(tǒng)代碼中執(zhí)行。由于保護模式下的代碼有優(yōu)先級之分,因此出現(xiàn)了從優(yōu)先級低的應用程序轉移到優(yōu)先級高的系統(tǒng)代碼中的問題,如果優(yōu)先級低的代碼能夠任意調(diào)用優(yōu)先級高的代碼,就相當于擁有了高優(yōu)先級代碼的權限。為了使高優(yōu)先級的代碼能夠安全地被低優(yōu)先級的代碼調(diào)用,保護模式下增加了門的概念。

 

門,指向某個優(yōu)先級高的程序所規(guī)定的入口點,所有優(yōu)先級低的程序調(diào)用優(yōu)先級高的程序只能通過門重定向,進入門的規(guī)定的入口點。這樣可以避免低級別的程序代碼從任意位置進入優(yōu)先級高的程序的問題。

 

保護模式下的中斷和異常等服務程序也要從門進入,80386的門分為中斷門、自陷門和任務門幾種。

 

在保護模式下要表示一個中斷或異常服務程序的信息需要用8個字節(jié),包括門的種類以及xxxx:yyyyyyyy格式的入口地址等。這組信息叫做中斷描述符。這樣,中斷向量表就無法采用和實模式下同樣的4字節(jié)一組的格式。

保護模式下把所有的中斷描述符放在一起組成“中斷描述符表”IDTInterrupt Descriptor Table)。IDT不再放在固定的地址00000h處,而是采用可編程設置的方式,支持的中斷數(shù)量也可以設置。為此80386處理器引入了一個新的48位寄存器IDTRIDTR的高32位指定了IDT在內(nèi)存中的基址(線性地址),低16位指定了IDT的長度,相當于指定了可以支持的中斷數(shù)量。

 

保護模式下發(fā)生異常或中斷時,處理器先根據(jù)IDTR寄存器得到中斷描述符的地址,然后取出n號中斷/異常的門描述符,再從描述符中得到中斷服務程序的地址xxxx:yyyyyyyy,經(jīng)過段地址轉換后得到服務程序的32位線性地址并轉移后執(zhí)行。

 

由于保護模式下用中斷門可以從低優(yōu)先級的代碼調(diào)用高優(yōu)先級的代碼,所以不能讓用戶程序寫中斷描述符表,否則會引發(fā)安全問題(CIH病毒)。這樣就如同關了窗子擋住蒼蠅,也擋住了微風,用戶的系統(tǒng)擴展程序也就不能像在DOS中一樣再用中斷服務程序的方式提供服務了。因為用戶程序根本沒有權限將中斷地址指到自己的代碼中來。

 

 

Windows中,操作系統(tǒng)使用動態(tài)鏈接庫來代替中斷服務程序提供系統(tǒng)功能,所以Win32匯編中int指令也就失去了存在的意義。這就是在Win32匯編源代碼中看不到int指令的原因。其實那些調(diào)用API的指令原本是用int指令實現(xiàn)的。

 

 

80386的保護機制

80286之前的處理器只支持單任務,操作系統(tǒng)并沒有什么安全性可言,計算機的全部資源包括操作系統(tǒng)的內(nèi)部都可以任憑程序員調(diào)用。

但對于多任務的操作系統(tǒng),某個搗亂的程序的為所欲為令即可使所有程序都無法運行。

所以80286及以上的處理器引入了優(yōu)先級的概念。80386處理器共設置4個優(yōu)先級(0~3)。0級是最高級(特權級);3級是最低級(用戶級);1級和2級介于它們之間。特權級代碼一般是操作系統(tǒng)的代碼,可以訪問全部系統(tǒng)資源;其他級別的代碼一般都是用戶程序,可以訪問的資源受到限制。

 

80386采用保護機制主要為了檢查和防止低級別代碼的越權操作,如訪問不該訪問的數(shù)據(jù)、端口以及調(diào)用高優(yōu)先級的代碼等。保護機制主要由下列幾方面組成:

1)段的類型檢查——段的類型是由段描述符指定的,主要屬性有是否可執(zhí)行,是否可讀和是否可寫等。而CSDSSS等段選擇器是否能裝入某種類型的段描述符是有限制的。如不可執(zhí)行的段不能裝入CS;不可讀的段不能裝入DSES等數(shù)據(jù)段寄存器;不可寫的段不能裝入SS等。如果段類型檢查通不過,則處理器會產(chǎn)生一般性保護異常或堆棧異常。

 

2)頁的類型檢查——除了可以在段級別上指定整個段是否可以讀寫外,在頁表中也可以為每個頁指定是否可寫。對特權級下的執(zhí)行代碼,所有的頁都是可寫的。但對123級的代碼,還要根據(jù)頁表中的R/W項決定是否可寫,企圖對只讀的頁進行寫操作會產(chǎn)生頁異常。

 

3)訪問數(shù)據(jù)時的級別檢查——優(yōu)先級低的代碼不能訪問優(yōu)先級高的數(shù)據(jù)段。

       80386的段描述符中有一個DPL域(描述符優(yōu)先級),表示這個段可以被訪問的最低優(yōu)先級。而段選擇器中含有RPL域(請求優(yōu)先級),表示當前執(zhí)行代碼的優(yōu)先級。只有DPL在數(shù)值上大于或等RPL值的時候,該段才是可以訪問的,否則會產(chǎn)生一般性保護異常。

 

4)控制轉移的檢查——在處理器中,有很多指令可以實現(xiàn)控制轉移,如jmpcallretintiret等指令。但優(yōu)先級低的代碼不能隨意轉移到優(yōu)先級高的代碼中,所以遇到這些指令的時候,處理器要檢查轉移的目的位置是否合法。

 

5)指令集的檢查——有兩類指令可以影響保護機制。

       第一類是改變GDTLDTIDT以及控制寄存器等關鍵寄存器的指令,稱為特權指令;       第二類是操作I/O端口的指令以及clisti等改變中斷允許的指令,稱為敏感指令。試想一下,如果用戶程序可以用sti禁止一切中斷(包括時鐘中斷),那么整個系統(tǒng)就無法正常運行,所以這些指令的運行要受到限制。特權指令只能在優(yōu)先級0上才能運行,而敏感指令取決于eflags寄存器中的IOPL位。只有IOPL位表示的優(yōu)先級高于當前代碼段的優(yōu)先級時,指令才能執(zhí)行。

 

6I/O操作的保護——I/O地址也是受保護的對象。因為通過I/O操作可以繞過系統(tǒng)對很多硬件進行控制。80386可以單獨為I/O空間提供保護,每個任務有個TSS(任務狀態(tài)段)來記錄任務切換的信息。TSS中有個I/O允許位圖,用來表示對應的I/O端口是否可以操作。某個I/O地址在位圖中的對應數(shù)據(jù)位為0則表示可以操作;如果為1則還要看eflags中的IPOL位,這時只有IOPL位表示的優(yōu)先級高于等于當前代碼段的優(yōu)先級,才允許訪問該I/O端口。

 

 

Windows的保護機制

Windows下,操作系統(tǒng)運行于0行,應用程序運行于3級。因為Alpha計算機只支持兩個優(yōu)先級,為了便于將應用程序移植到Alpha計算機上,Windows操作系統(tǒng)不使用12級這兩個優(yōu)先級。

 

Windows操作系統(tǒng)充分利用80386的保護機制,所有和操作系統(tǒng)密切相關的東西都是受保護的。運行于優(yōu)先級3上的用戶程序有很多限制,只有在寫VxD等驅動程序的時候才可以使用全部資源。在Win32匯編編程中要注意避免以下的越權操作(當然寫驅動程序不在此列):

 

1)顯而易見,所有的特權指令都是不可執(zhí)行的,如lgdtlldtlidt指令和對CRxTRx等寄存器賦值。但是,讀取重要寄存器的指令是可以執(zhí)行的,如sgdtsldtsidt等。

 

2Windows在頁表中把代碼段和數(shù)據(jù)段中的內(nèi)存賦予不同的屬性。代碼段是不可寫的,數(shù)據(jù)段中也只有變量部分的頁面是可寫的。所以雖然可以尋址所有的4GB空間,但訪問越出權限規(guī)定以外的東西還是會引發(fā)保護異常。

 

3)在Windows 98中,系統(tǒng)硬件用的I/O端口是受保護的,但其余的則可以操作。如果用戶在機器中插入一塊自己的卡,用的是300h系統(tǒng)未定義的端口,那么在應用程序中就可以直接操作,但要操作3f8h(串口)和1f0h(硬盤端口)等系統(tǒng)已定義的端口就不行了。在Windows NT中,任何的端口操作都是不允許的。

 

如果違反了Windows規(guī)定的“保護條例”,那么會引發(fā)保護異常,處理器會毫不猶豫地把控制權轉移到對應的異常處理程序中去。Windows會在處理程序中用一個很酷的“非法操作”對話框把用戶的程序判死刑,沒有一點回旋的余地!在Windows 9x中,系統(tǒng)有時會用一個藍屏幕來通知用戶程序試圖訪問不存在的內(nèi)存頁。

 

如果程序調(diào)用的DLL中有錯,那么錯誤還是會算在應用程序頭上,因為DLL的地址空間是被映射到應用程序的空間中去的。Windows 9x本身是32位和16位混合的操作系統(tǒng),為了兼容DOSWin16程序,很多的保護措施做起來力不從心。所以系統(tǒng)內(nèi)部反而常常出現(xiàn)越權操作,以至于藍屏幕不斷,這些就不是用戶應用程序自己的問題了。

 

posted on 2010-08-06 13:42 luqingfei 閱讀(2221) 評論(1)  編輯 收藏 引用 所屬分類: Win32匯編程語言序設計

評論

# re: Win32匯編--需要了解的基礎知識 2014-04-23 02:28 solq

哇,哥,連書里的內(nèi)容都打上了,這花了不少時間吧
。。。。。。  回復  更多評論   

導航

<2010年8月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
2930311234

統(tǒng)計

留言簿(6)

隨筆分類(109)

隨筆檔案(105)

Blogers

Game

Life

NodeJs

Python

Useful Webs

大牛

搜索

積分與排名

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久精品亚洲一区| 亚洲第一视频网站| 欧美在线看片a免费观看| 99这里有精品| 9i看片成人免费高清| 亚洲视频精选在线| 亚洲欧美日韩一区二区三区在线观看 | 欧美一区二区日韩| 欧美中日韩免费视频| 久久久久久久综合色一本| 麻豆成人在线播放| 亚洲国产精品久久精品怡红院| 欧美福利在线| 亚洲最新视频在线| 久久精品人人做人人爽| 欧美激情亚洲视频| 国产欧美日韩不卡| 亚洲日产国产精品| 欧美亚洲网站| 亚洲大黄网站| 亚洲黄色尤物视频| 亚洲欧美电影在线观看| 蜜臀久久99精品久久久久久9| 91久久线看在观草草青青| 亚洲亚洲精品三区日韩精品在线视频| 久久久成人网| 国产精品久久久久av| 亚洲高清久久网| 欧美影院成人| 99re66热这里只有精品4| 久久精品国产第一区二区三区最新章节 | 99国产精品久久| 欧美专区在线观看| 亚洲精品婷婷| 免费在线日韩av| 好看的亚洲午夜视频在线| 在线午夜精品| 欧美激情四色| 久久久久久久综合日本| 国产精品国产三级国产普通话蜜臀| 亚洲一区二区在线免费观看| 玖玖综合伊人| 国产拍揄自揄精品视频麻豆| 9色porny自拍视频一区二区| 久久综合99re88久久爱| 在线亚洲国产精品网站| 欧美激情综合色| 亚洲精品1区2区| 理论片一区二区在线| 欧美一区二区大片| 国产精品综合久久久| 午夜精品999| 一区二区精品| 国产精品sm| 亚洲一级二级| 中文网丁香综合网| 国产精品va在线播放| 亚洲无线视频| 一区二区三区久久精品| 欧美人与性动交cc0o| 99视频在线观看一区三区| 亚洲福利视频二区| 欧美国产精品一区| 日韩一二三区视频| 亚洲精品一区二区三区四区高清| 欧美福利网址| 一区二区三区国产| 一区二区三区四区五区视频| 国产精品成人一区二区三区吃奶| 99国产一区二区三精品乱码| 一区二区三区福利| 国产精品亚洲综合天堂夜夜| 久久精品国产久精国产一老狼| 午夜精品在线| 尤物精品在线| 91久久夜色精品国产九色| 欧美视频专区一二在线观看| 亚洲欧美日韩区| 久久久久久久久久码影片| 欧美影院精品一区| 在线免费观看欧美| 亚洲精品一区二| 国产欧美日韩伦理| 免费在线视频一区| 欧美日韩国产成人在线免费| 午夜精品久久久久| 久久精品理论片| 亚洲精品一区二区网址| 亚洲婷婷国产精品电影人久久| 国产综合色精品一区二区三区| 欧美xxx成人| 欧美日韩一级视频| 久久亚洲精品一区| 欧美噜噜久久久xxx| 亚洲欧美卡通另类91av| 久久精品123| 日韩一级裸体免费视频| 亚洲欧美一区二区三区久久| 亚洲国产一区二区三区高清| aa级大片欧美| 1000部国产精品成人观看| 亚洲精选国产| 久久伊伊香蕉| 中文亚洲字幕| 久久久免费观看视频| 亚洲一区二区三区激情| 久久婷婷久久一区二区三区| 亚洲一区二区成人| 欧美成人自拍| 久久婷婷久久一区二区三区| 欧美视频精品在线| 欧美激情视频在线免费观看 欧美视频免费一 | 亚洲美洲欧洲综合国产一区| 狠狠色狠狠色综合日日91app| 亚洲精品黄网在线观看| 精品不卡在线| 欧美一级欧美一级在线播放| 亚洲无线观看| 欧美日韩午夜在线| 亚洲国产高清在线| 亚洲国产精品va| 久久电影一区| 欧美资源在线观看| 国产精品一区二区你懂的| 亚洲日本无吗高清不卡| 亚洲高清资源| 美女精品在线观看| 久热爱精品视频线路一| 国产在线播精品第三| 香蕉成人伊视频在线观看 | 欧美日韩卡一卡二| 亚洲精品日日夜夜| 性欧美暴力猛交69hd| 亚洲女同同性videoxma| 欧美日韩在线影院| 亚洲免费观看| 一区二区三区你懂的| 免费亚洲网站| 亚洲人成在线观看| 夜色激情一区二区| 欧美区高清在线| av成人天堂| 亚洲欧美一区二区三区久久| 欧美网站大全在线观看| 亚洲午夜极品| 欧美一级夜夜爽| 国产专区欧美专区| 久久久久久久综合色一本| 欧美成人官网二区| av不卡在线| 国产精品中文字幕在线观看| 欧美一区二区三区的| 免费美女久久99| 亚洲美女av网站| 欧美日韩激情小视频| 亚洲午夜91| 久久久久久电影| 亚洲欧洲中文日韩久久av乱码| 欧美精品情趣视频| 亚洲一区二区三区久久| 久久久蜜桃一区二区人| 亚洲精品久久久久久久久久久久久 | 久久九九热re6这里有精品| 久久久91精品国产| 亚洲激情亚洲| 国产精品每日更新| 久久精品一本| 亚洲久久一区二区| 久久国产精品电影| 91久久精品国产| 欧美三级日本三级少妇99| 亚洲欧美日韩精品一区二区| 欧美成人一区二区三区在线观看 | 免费在线国产精品| 亚洲每日在线| 国内精品视频在线观看| 欧美日韩国产一区二区三区地区| 欧美亚洲自偷自偷| 99av国产精品欲麻豆| 久久久久久久综合狠狠综合| 99热在线精品观看| 精品电影在线观看| 国产精品萝li| 欧美日本视频在线| 久久久一区二区| 亚洲综合视频网| 亚洲免费观看高清完整版在线观看熊| 久久久久久国产精品mv| 亚洲欧美视频在线观看| 日韩午夜免费视频| 在线观看视频一区| 国产精品尤物| 欧美深夜影院| 欧美韩日一区| 老司机成人网| 久久久久国产精品人| 性8sex亚洲区入口| 亚洲视频在线观看三级| 亚洲精品一区二区在线观看| 欧美激情乱人伦|