2013-03-11 32 views
1

假設我的API是從一個只能在實模式或大實模式下工作的系統調用的。我的API應該顯示當前的系統模式。那麼它怎麼能知道當前模式是實模式還是大實模?如何知道當前模式是真實模式還是大實模?

注:

  1. 在大實模式保護模式啓用CR0位被禁止的,因此檢查它沒有任何區別。
  2. 儘管A20地址線已啓用,但並不表示它處於大實模式。

回答

0

在大實模式下,實模式地址別名會失敗。假設您處於大實模式,並且您的DS的值爲0x6000。由於DS的描述符緩存已被重載(大實模式的定義),因此DS:0的物理地址不是0x60000。如果用另一個段寄存器命中0x60000,那將不會是相同的內存位置。

所以這是一個配方。在數據段中創建一個臨時變量。請注意其相對於DS的offset。使用DS-1的值加載ES,更改變量的值,並查看ES(offset + 0x10)上是否有相同的值。爲了防止誤報,請做兩次。

這不會檢測虛擬86模式。另外,如果ES通過緩存描述符指向高內存,那麼當您重新加載ES時,這將會丟失。確保調用者代碼不會依賴ES保持不變。

大實模式本身不是CPU模式 - 沒有寄存器位表示「我們現在處於大真實狀態」。這只是一種使用香草實模式的i386特定邏輯來訪問高內存的方法。上述程序只檢查DS是否已經這樣處理;根據實現情況,DOS擴展器可能通過ES描述符重新加載實現了大實數,同時保持DS vanilla。維基百科說,有時甚至CS也會以這種方式造成混淆,儘管這是一個棘手的命題,因爲中斷。

+0

BRM與別名無關。段基地址保持相等'段值* 0x10'。但是,段限制設置爲大於0xFFFF的值,允許偏移量> = 0x10000。這就是BRM的重點。 – 2013-03-11 22:23:16

1

如果執行此:

mov ebx, 0x10000 
mov al, [ebx] 

,並得到一個#GP,然後DS段描述符具有0xFFFF的原有限制,這是正常的真實地址模式和虛擬8086模式的情況下。

如果您沒有從mov al, [ebx]得到#GP,原始限制已經擴展到0xFFFF以上(通常爲0xFFFFFFFF,但不一定如此)。

順便說一句,檢查v86模式可能也可能應該在嘗試上述之前完成(如果您的主機操作系統沒有正確地反映您的處理程序異常)。執行smsw即可獲得cr0.pe。它將在v86模式下設置爲1,在實際地址模式下設爲0。直接用mov讀取cr0將在v86模式下生成#GP,這就是爲什麼smsw是首選方法。

0

在90年代初期,我們使用了一種未公開的方法讓我們能夠以真實模式訪問4Gig(現在可以稱爲BIG REAL MODE)。該方法將進入保護模式,將粒度位更改爲1(意味着4K粒度而不是1個字節的粒度),然後返回實模式並將所有段寄存器設置爲0.然後可以使用ebx等訪問4Gig的內存。

所以如果這就是你所說的,試着去保護模式並檢查粒度位的設置。對不起,我所有的舊手冊都在閣樓上。如果你需要這些信息,我可以把它們挖出來。

相關問題