全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4451
推到 Plurk!
推到 Facebook!

DOS實方式下直接訪問4GB記憶體

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-09 15:22:12 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料    http://depos.patching.net/showart.asp?art_id=80&cat_id=5    DOS實方式下直接訪問4GB記憶體    DOS實方式下直接訪問4GB記憶體  陳家祺  摘 要 本文分析了80486CPU的定址機制,提出了在實方式下直接訪 問4GB記憶體的策略和C程式設計方法。 關鍵字 DOS程式 擴展記憶體 程式設計  Scheme of the Direct Access 4GB Memory  in DOS Real Mode  Chen Jiaqi ABSTRACT This paper makes an analysis of the principle about the access operation of 80486CPU, a approaches are posed for access 4GB memory and C Programming. KEY WORDS DOS program; XMS; Programming; 0 引 言 在高檔PC微機系統中,如80486CPU微機系統,應用軟體的開發可以基於DOS系統的實方式,也可以基於Windows和OS/2系統的保護方式。如何在DOS系統的實方式下開發具有訪問擴展記憶體的應用程式,這是廣大軟體發展者關心的問題。其主要原因是:DOS系統是在PC機中應用最廣泛的作業系統,經過廣大用戶長年的應用和面向實際的軟體發展,其介面特性和編程方法被廣大軟體發展者所熟悉和掌握,並積累了豐富的應用程式資源、一系列功能強大的開發工具和一支巨大的DOS軟體發展隊伍。然而,開發基於DOS系統的實方式應用程式存在一定的局限性,主要是不能有效地利用高檔微機的記憶體資源,如擴展記憶體的訪問。尤其在開發即時性很強的大資料量的應用程式中,高效使用擴展記憶體是極?重要的。 目前常用的訪問擴展記憶體方法有:(1)採用“INT 15H”或HIMEM.SYS的功能調用。(2)採用虛擬磁片。前者只能實現資料塊在常規記憶體與擴展記憶體之間移動,這樣,不但還要佔用一定的常規記憶體空間,而且資料塊的移動還需佔用程式運行時間,使程式的運行效率降低。後者可以以文件的形式將資料存儲在擴展記憶體中,採用文件的訪問方式進行資料操作。顯然,這二種方法只能間接訪問擴展記憶體,不能直接訪問擴展記憶體。最大的缺點是資料的操作效率低,難以滿足即時性要求。 本文將從80486CPU(以下簡稱CPU)的定址機制研究入手,討論在實方式下直接訪問4GB記憶體的方法和C程式設計方法。 1 基本原理 1.1 物理位址形成的統一性 無論CPU在實方式下或保護方式下,其物理位址的形成都將使用段描述符高速緩衝寄存器。其差別是: 在實方式下,每當向段寄存器賦予新的內容(段地址)時,段描述符高速緩衝寄存器的基底位址值相應發生改變,其值?16×SEG,這就線性基底位址;CPU最終形成的物理位址?基底位址值加偏移量。段描述符高速緩衝寄存器的界限值和屬性值始終不變。當CPU重定後,CPU的工作模式?實方式,段描述符高速緩衝寄存器的界限值自動設置?FFFFH。因此,CPU能夠訪問記憶體的空間?0~10FFEFH(FFFFH×16+FFFFH),每個段的大小?64KB。 在保護方式下,每當向段寄存器賦予新的內容SEL(選擇字)時,段描述符高速緩衝寄存器的內容將由SEL對應的段描述符更新;段描述符高速緩衝寄存器的基底位址值、界限值和屬性值依據段描述符的設置而發生改變。段的基底位址可設置在4GB記憶體的任意位址處,段的最大界限值可達FFFFFFFFH(4GB-1)。在不分頁的情況下,CPU最終形成的物理位址同樣是基底位址值加偏移量。所以,CPU能夠整個訪問4GB記憶體空。 顯然,對於CPU在形成物理位址時,在實方式下與在0特權級不分頁的保護方式下是相同的。只是段的基底位址和段的大小設置範圍不同。工作方式確定是由控制寄存器CR0的最低位PE位決定的,若PE?0,則工作在實方式;若PE?1,則工作在保護方式。在通過PE位的改變時,就進行了工作方式切換。這種切換只影響段描述符高速緩衝寄存器的基底位址值運算方式,不影響段描述符高速緩衝寄存器的段界限值。 1.2 直接訪問4GB記憶體 當CPU重定後,CPU處於實方式下,儘管在實方式下可執行諸如“MOV AX,[ESI]”指令的32位元寄存器間接定址操作,但是ESI的內容必須在0~FFFFH範圍內,否則,將引起13號異常中斷。 基於CPU物理位址形成的統一性,在實方式下直接訪問4GB記憶體的關鍵是擴大段描述符高速緩衝寄存器的界限值。使諸如“MOV AX,[ESI]”指令的32位元寄存器間接定址操作實現4GB記憶體的訪問。然而,CPU在實方式下並沒有提供改變段描述符高速緩衝寄存器的界限值的操作指令。改變段描述符高速緩衝寄存器的內容只能在保護方式下進行,即向段寄存器賦予段的選擇字SEL,段描述符高速緩衝寄存器的內容將由SEL對應的段描述符更新。當CPU從保護方式切換到實方式時,段描述符高速緩衝寄存器的內容不發生變化。 因此,在DOS實方式下直接訪問4GB記憶體之前,讓CPU進入保護方式下,通過裝載具有4GB界限的段描述符到段描述符高速緩衝寄存器中去。然後返回到實方式下。CPU就可以通過32位寄存器間接定址操作實現4GB記憶體的訪問。 2 C程式設計 2.1 編程環境 本文採用Borland C++ 3.1程式設計環境,在程式中使用內嵌彙編方法實現特定的操作,在OPtions的“Compile”-“Advanced Code generation”中選擇386指令集。由於集成開發環境下的內部編譯器不能識別內嵌的386彙編指令,對於32位元寄存器和32位元位址操作彙編指令,可以採用直接在代碼前加入運算元字首0x66或位址字首0x67,以便實現32位寄存器或地址的操作。最好的方法是讓集成開發環境調用TASM.EXE進行編譯,即設置OPtions中的“Compile”-“Code generation”-“Compile via assemler”?ON。這樣便可完整地運用386彙編指令,在以下編程示例中採用這種編譯方法。 本程式是採用基於實方式下的編程方法。它不能在保護方式下和虛擬8086方式下運行,不能裝載延伸記憶體EMS驅動程式(如EMM386.EXE),因?,它使DOS系統處於虛擬8086方式下。 2.2 打開A20地址線 CPU的A20位址線受到鍵盤介面處理器8042的輸出口P21控制,如果DOS系統在?動後,沒有裝載XMS驅動程式(如himem.sys),此時A20被關閉,要訪問4GB記憶體,必須打開A20,使A20受到CPU的控制。 void openA20() { while(inp(0x64) & 2); outp(0x64,0xd1); while(inp(0x64) & 2); outp(0x60,0xdf); while(inp(0x64) & 2); outp(0x64,0xff); } 2.3 設置資料段的4GB界限函數 首先,建立一個全局描述符表GDT,即GDT_def,它含有二個描述符,第一個?空描述符(保護方式下系統要求的),第二個是具有4GB段界限的資料段描述符。它的選擇字?8。再計算出GDT的基底位址和長度存入GDT_Addr中。然後,裝載GDT,進入保護方式,把選擇字8賦給DS和ES,此時第二個是具有4GB段界限的資料段描述符被裝載到DS和ES的描述符高速緩衝寄存器中。最後返回實方式。同理,也可設置FS和GS的4GB界限。 unsigned long GDT_def[]={0,0,0x0000FFFF,0x008F9200}; //全局描述符表GDT unsigned char GDT_Addr[6]={0}; //存放GDT的基底位址和長度 void set4gb()  { asm{ cli push ds ; push es mov word ptr GDT_Addr[0], (2*8-1) //GDT的長度存入GDT_Addr中 mov eax,ds //計算GDT描述符表的線性基底位址31-0 shl eax,4 //段地址eax=ds×16 xor ebx,ebx //ebx清零 mov bx,offset GDT_def //bx=GDT的偏移地址 add eax,ebx //GDT的線性基底位址=eax+ebx mov dword ptr GDT_Addr[2],eax //GDT的線性基底位址存入GDT_Addr中 lgdt fword ptr GDT_Addr  mov bx,8 //設置資料段描述符的選擇字 mov eax,cr0 or al,1 mov cr0,eax jmp flush1 } //進入保護方式 flush1: asm{ mov ds,bx //DS裝載具有4GB界限的資料段描述符 mov es,bx //ES裝載具有4GB界限的資料段描述符 and al,0feh mov cr0,eax jmp flush2 } //返回實方式 flush2: asm{ pop es ; pop ds sti } } 2.4 直接訪問4GB記憶體的基本函數 在DS和ES具有4GB的訪問界限後,通過32位元寄存器間接定址的指令就可實現4GB記憶體的訪問。以下僅給出位元組的讀寫函數,其中,addr?RAM的32位元線性位址。 (1)讀位元組函數 ,函數的返回值?讀出的位元組。 unsigned char read_ram(unsigned long addr)  { asm push ds asm mov ax,0 asm mov ds,ax asm mov esi,addr asm mov al,[esi] asm pop ds return _AL; } (2)寫位元組函數,chr?要寫入的位元組。 void write_ram(unsigned long addr,unsigned char chr)  { asm push ds  asm mov ax,0 asm mov ds,ax asm mov esi,addr asm mov al,chr asm mov [esi],al asm pop ds } 2.5 程式示例 本示例將使用上面所設計的功能函數,由內嵌組合語言程式完成對主機記憶體的測試和容量的檢測任務。在PC386/33、PC486/100上通過。 #include  #include void main() {unsigned long addr; openA20(); set4gb(); asm push ds asm mov ax,0 asm mov ds,ax asm mov esi,00100000h //從1Mb開始測試 N1: asm mov eax,[esi] //暫存esi地址指定雙字單元的內容 asm mov dword ptr [esi],0//向esi地址指定雙字單元寫零 asm mov ebx,[esi] //讀出由esi地址指定的雙字單元的內容給ebx asm mov dword ptr [esi],0ffffffffh//向esi地址指定雙字單元寫全1 asm mov ecx,[esi] //讀出由esi地址指定的雙字單元的內容給ecx asm mov [esi],eax //恢復esi地址指定雙字單元的內容 asm inc ecx //若ecx的內容?全1,ecx增一後,ecx=0 asm cmp ebx,ecx //比較兩次讀出的內容 asm jne N2 //不相等,則退出迴圈檢測 asm add esi,4 //esi地址增4 asm jmp N1 //繼續迴圈檢測 N2: asm mov addr,esi asm pop ds printf("RAM = %ld(Mb)", addr >> 20 ); } 3 與XMS驅動程式的相容方法 3.1 基本原理 如果沒有裝載XMS驅動程式Himem.sys,採用上述方法可無限制地使用整個擴展記憶體。若系統中的某些系統程式和其他應用程式需要使用Himem.sys,通過它分配和訪問擴展記憶體。這樣,擴展記憶體的部分空間被佔據,用戶應用程式所使用的擴展記憶體空間將受到限制,否則,發生衝突。 因此,在這種情況下,用戶應用程式可通過Himem.sys的功能調用,?其分配未使用的擴展記憶體存儲塊EMB,並通過鎖定EMB,得到EMB的32位元線性基址。便可採用上述方法對存儲塊進行直接訪問。 3.2 Himem.sys的介面 (1)取得安裝狀態 只有當Himem.sys已被載入,才能調用它的功能。當AX=4300H時,執行“INT 2FH”軟中斷指令後,若AL=80H,則已載入;若AL=00H,則未載入。 (2)取得入口地址 Himem.sys的各項功能調用是通過功能調用的入口地址進行的,當AX=4310H時,執行“INT 2FH”軟中斷指令後,ES=入口的段位址,BX=入口的偏移地址。 (3)功能調用 Himem.sys?用戶提供許多XMS的記憶體管理功能,與本文相關的功能和介面如表1所示。 表1 HIMEM.SYS的主要功能與介面 功 能 入 口 出 口 取得空EMB (擴展存儲塊)資訊 AH=08H CALL HIMEM.SYS的入口地址 AX=最大連續的空EMB容量(KB) DX=總計空EMB容量(KB) 請求分配EMB AH=09H DX=存儲塊長度(KB) CALL HIMEM.SYS 的入口地址 AX=0001H 成功 DX=已分配EMB的控制碼 AX=0000H 失敗 DX=NULL 釋放EMB AH=0AH DX=要釋放已分配EMB的控制碼 CALL HIMEM.SYS的入口地址 AX=0001H 成功 AX=0000H 失敗 鎖定EMB AH=0CH DX=要鎖定的EMB的控制碼 CALL HIMEM.SYS的入口地址 AX=0001H 成功 DX:BX?EMB的32位元線性基底位址 AX=0000H 失敗 解除鎖定的EMB AH=0DH DX=解除被鎖定的EMB的控制碼 CALL HIMEM.SYS的入口地址 AX=0001H 成功 AX=0000H 失敗 4 結束語 DOS實方式下直接訪問4GB記憶體具有一定的特殊性和重要的實際意義。本文提出的方法在圖像即時識別系統中得到了成功的應用。該系統需同時採集四幅圖像,每幅圖像?512×512的256色點陣,四幅圖像共需1MB記憶體空間,在對圖像進行處理時還需要二幅圖像的工作緩衝區。顯然,在常規記憶體中難以進行存儲和處理。若採用虛擬磁片或XMS驅動程式Himem.sys,由於圖像的資料量大,運算時間長,影響了即時性要求。通過採用本文提出的方法,運用C程式的內嵌彙編直接對擴展記憶體進行圖像的存儲和處理。發揮了電腦的最大運行效率,滿足了即時性要求。因此,本文提出的方法不但能應用於圖像處理系統,而且也適用于其他應用領域。其特點是:編程簡單、實現容易。可充分發揮和利用電腦的記憶體資源。 參 考 文 獻 1 陳家祺. DOS實方式下的保護方式程式設計方法. 湖北汽車工業學院學報,1997(1) 2 陳家祺. DOS應用程式使用擴展記憶體的C程式設計方法. 湖北汽車工業學院學報,1997(1) 3 朱傳乃. 386/486微型電腦系統原理與維修. 北京:人民郵電出版社,1995 4 何希才等. 80486微型電腦的原理及應用. 北京:人民郵電出版社,1994 5 周明德等. 80x86/80x87的結構與組合語言程式設計. 北京:清華大學出版社,1993 ********************************************************* 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together! 希望能大家敞開心胸,將知識寶庫結合一起
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-11-21 20:25:04
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!