這幾天在看《windows環境下32位彙編程式設計》,接觸到了一些計算機底層的東西,是我以前了解不到的,由於知識比較繁煩,所以特把一些東西記錄下來,方便以後查閱。
在dos中,彙編中最先開始接觸的就是記憶體定址了,dos狀態下,作業系統的記憶體管理與windows的記憶體管理有著截然不同的方法。其實,說白了,win32程式設計相對於dos程式設計最大的不同就是記憶體的使用。
對於dos來說,是執行於實模式下的,實模式是相對於8086的機器,定址範圍只有1m的空間,也就是00000h-fffffh,凡獲得的位址值都不可在這個界區之外。而對於這短短的1m空間來說,系統硬體位址的安排又占去了記憶體高階的一些空間(從a0000h-fdc000h,計384kb),在系統記憶體的低端,安排了中斷向量表和bios資料區(000000h-000500h,計1k位元組),剩下的不到640k就是作業系統和應用程式所共享的記憶體(此謂著名的640kb記憶體限制)。
dos下的定址是根據段暫存器ds×10h+段偏移得出來的,得出來的值就是物理記憶體中相應位址的值。如***x:yyyy格式的虛擬位址在記憶體中的實際位置就是***x*10h+yyyy。
windows的記憶體管理和dos記憶體管理有著很大的不同,windows可以執行在實模式,保護模式,虛擬8086模式下,當執行在實模式下時,定址是跟dos沒有任何分別的,定址為1m空間,但是在保護模式與虛擬8086模式下,則有著本質的不同,因為在這些模式下,32位的位址線可訪問達4gb的記憶體位址,以前的段位址加段偏移無法覆蓋如此大的空間。因為在386的結構中,暫存器已擴至32位,所以,暫存器的值就可以直接表示記憶體中某個位址,而無需用乙個段暫存器來作間接定址。
那麼,在386模式下,段暫存器起什麼作用呢?它不是用作基址,而是用作段選擇器,在保護模式下,乙個位址空間是否可以被寫入,可以被多少優先順序寫入,是不是允許執行等保護的問題都是需要考慮的。所以,必須對乙個位址空間定義一些安全上的屬性,段描述符就是被派上作此用途。段描述符是64位,但在386中,段暫存器卻是16位,空間不夠,放不下。解決辦法是把段描述符組成乙個表結構,而用段暫存器來作索引。所以,在386中,段暫存器也叫做了段選擇器。
在386中,引入了兩個新的暫存器來管理段描述符,乙個是48位的全域性描述表暫存器gdtr,乙個是16位的區域性描述表暫存器ldtr。在windows中,記憶體的表示是以***x:yyyyyyyy表示,下面介紹一下他是怎麼定址的:
首先,***x是無法表示段的基址的,對於這個位址,首先要看***x的ti位是否為0(即***x的第二位),如果是,則從gdtr中獲取gdt的基址,然後在gdt中以段選擇器***x的高12位得出索引,根據索引偏移找到相應的段描述符,段描述符包括段的基址,限長,優先順序各種屬性,這就得到了段的起始位址,加上yyyyyyyy即是要找的記憶體的線性位址zzzzzzzz。 如果ti位為1,則表示段描述符放在ldt中,第一步的操作還是從gdtr中獲取gdt的基址,然後從ldtr暫存器獲得索引(非***x的高十二位),注意,這時根據索引偏移得到得並不是段描述符,而是得到ldt段的位置,然後根據***x的高十二位從ldt段中獲得段描述。再以這個段描述符資訊得到段基址,再加上偏移yyyyyyyy得到要找的線性位址zzzzzzzz。可以寫個簡單的模擬程式來表示:
if( ***x的第二位==1 ) //段描述符的位置在gdtr中
else //ti位為0,表示在段描述符在ldt中
關於windows字型的一些筆記
windows的字型管理在登錄檔的windows font這部分 具體路徑忘記了 這裡會記錄字型的名稱和名稱,如果有具體指出路徑,windows啟動的時候會從這個路徑去載入字型,沒有的話則在 系統盤 windows font 這個資料夾裡面,載入失敗則忽略 如果在安裝字型的時候沒有寫入這個登錄檔,則...
一些看英語文件的筆記
dos cmd set path path c python33 control d on windows control z on unix 在linux下 usr bin env python33 原始檔編碼 coding gb2312 給許可權 chmod x pyname.py 在互動模式中...
彙編的一些程式
led閃爍的簡單試驗 org 0000h 程式從此位址開始執行 ljmp main 跳轉到 main 程式處 org 030h main 從030h處開始 main mov p2 00h p2為低電平 led 燈亮 acall delay 呼叫延時子程式 mov p2 0ffh acall dela...