1,當80386處理器工作在保護模式和虛擬8086模式的時候,可以使用全部32根地址線訪問4 GB大的內存。段地址加偏移地址的計算方法顯然無法覆蓋這么大的范圍。但計算一下就可以發現,實際上和8086同樣的限制已經不復存在,因為80386所有的通用寄存器都是32位的,2的32次方相當于4G,所以用任何一個通用寄存器來間接尋址,不必分段就已經可以訪問到所有的內存地址。
2,內存分頁管理只能在保護模式下才可以實現,實模式不支持分頁機制。但不管在哪種模式下,所有尋址指令使用的都是線性地址,程序不用關心數據最后究竟存放在物理內存的哪個地方。
3,Windows系統一般在硬盤上建立大小為物理內存兩倍左右的交換文件(文件名在Windows 9x下為Win386.swp,Windows NT下為PageFile.sys)用做虛擬內存。利用80386處理器的內存分頁機制,交換文件在尋址上可以很方便地作為物理內存使用。只需在真正訪問到的時候將硬盤文件的內容讀入物理內存,然后重新將線性地址映射到這塊物理內存就可以了。同樣道理,被執行的可執行文件也不必真正裝入內存,只要在頁表中建立映射關系,以后到真正訪問到的時候再調入物理內存。(win32的是不用關心物理地址的,它直接映射到線性地址,和實模式不同,實模式直接映射到物理地址)
4,由此可以引出Win32編程中幾個很重要的概念:
● 每個應用程序都有自己的4 GB的尋址空間。該空間可存放操作系統、系統DLL和用戶DLL的代碼,它們之中有各種函數供應用程序調用。再除去其他的一些空間,余下的是應用程序的代碼、數據和可以分配的地址空間。
● 不同應用程序的線性地址空間是隔離的。雖然它們在物理內存中同時存在,但在某個程序所屬的時間片中,其他應用程序的代碼和數據沒有被映射到可尋址的線性地址中,所以是不可訪問的。從編程的角度看,程序可以使用4 GB的尋址空間,而且這個空間是“私有”的。
● DLL程序沒有自己“私有”的空間。它們總是被映射到其他應用程序的地址空間中,當做其他應用程序的一部分運行。原因很簡單,如果它不和其他程序同屬一個地址空間,應用程序該如何調用它呢?
5,正因為如此,Windows操作系統干脆為用戶程序“安排好了一切”。具體表現在為用戶程序的代碼段、數據段和堆棧段全部預定義好了段描述符。這些段的起始地址為0,限長為ffffffff,所以用它們可以直接尋址全部的4 GB地址空間。程序開始執行的時候,CS,DS,ES和SS都已經指向了正確的描述符,在整個程序的生命周期內,程序員不必改動這些段寄存器,也不必關心它們的值究竟是多少(實際上,想改也改不了)。
所以對Win32匯編程序來說,整個源程序中竟然可以不用出現段寄存器的身影。這在DOS匯編編程中是不可想像的。回顧本節開頭提出的問題,答案是:并不是Win32匯編源代碼用不到段寄存器,而是用戶在使用中不必去關心段寄存器
6,在保護模式下,中斷或異常處理往往從用戶代碼切換到操作系統代碼中執行。由于保護模式下的代碼有優先級之分,因此出現了從優先級低的應用程序轉移到優先級高的系統代碼中的問題,如果優先級低的代碼能夠任意調用優先級高的代碼,就相當于擁有了高優先級代碼的權限。為了使高優先級的代碼能夠安全地被低優先級的代碼調用,保護模式下增加了“門”的概念。“門”指向某個優先級高的程序所規定的入口點,所有優先級低的程序調用優先級高的程序只能通過門重定向,進入門所規定的入口點。這樣可以避免低級別的程序代碼從任意位置進入優先級高的程序的問題。保護模式下的中斷和異常等服務程序也要從“門”進入,80386的門分為中斷門、自陷門和任務門幾種。