跳至內容

載入全部

出自Taiwan Tongues 繁中維基
這是此頁批准,以及是最近的修訂。

LOADALL 是 Intel 80286 與 Intel 80386 處理器中兩種不同但未記載的機器指令的通用名稱,其允許存取通常在 IA-32 API 範圍之外的處理器內部狀態區域,例如描述符快取暫存器。適用於 286 處理器的 LOADALL 編碼為 0Fh 05h,而適用於 386 處理器的 LOADALL 則為 0Fh 07h。

兩種變體——正如其名——皆在單一操作中載入所有 CPU 內部暫存器。LOADALL 具有獨特的能力,可以獨立於其對應的快取部分來設定區段暫存器的可見部分(選擇子),從而讓程式設計師能將 CPU 帶入官方程式設計模型所不允許的狀態。

用途

舉例來說,這些技術的實用之處在於,LOADALL 能設定 CPU 從真實模式存取所有記憶體,而無須切換至虛幻模式(該模式需要先切換至保護模式、存取記憶體,最後再切換回真實模式)。MS-DOS 中的 RAMDRIVE.SYS(1985)、SMARTDRV.SYS(1986)的 XMS 前版本,以及 HIMEM.SYS(2.03, 1988-08-04; 2.04, 1988-08-17)驅動程式、Uniform Software Systems 為 Lotus 1-2-3 開發的 The Extender(1985)與 The Connector(1985)、Above Disk(1986)(由 Above Software(前身為 Tele-Ware West,又名 Los Angeles Securities Group)開發的 LIMulator,可將硬碟空間或延伸記憶體轉換為擴充記憶體),以及 OS/2 1.0 和 1.1 都曾使用 286 的 LOADALL 指令。DOS 3.3 與 4.0 在 0070:0100h 位址保留了一個 102 位元組的緩衝區(該位置通常由 DOS BIOS 資料佔用),因此在使用 LOADALL 時無需儲存和還原該區域。微軟的 EMM386.EXE 在其無效操作碼處理常式中,對 286 和 386 的 LOADALL 指令進行了特殊處理。檢視 Windows/386 2.10 中的虛擬機器監視器程式碼可以發現,它同時使用了 286 版本及更鮮為人知的 386 變體。微軟的 HIMEM.SYS 2.06 版也曾使用 LOADALL,以便在 286 系統上快速地在延伸記憶體之間進行複製。

根據《The Design of OS/2》一書中所述,LOADALL 的另一個有趣用法,是允許在 16 位元保護模式下執行過去的真實模式程式,此技術自 1985 年起被 Digital Research 的 Concurrent DOS 286 所採用,並於 1986 年後應用於 FlexOS 286 與 IBM 4680 OS。將 GDT 和 LDT 中的所有描述符快取標記為「不存在」,能讓作業系統捕捉到區段暫存器的重載,以及執行真實模式特有的「區段運算」的嘗試,並透過更新區段描述符(再次使用 LOADALL)來模擬所需的行為。然而,這種為 80286 設計的「8086 模擬模式」速度太慢,不具實用性。由於早期 E-2 步進前的 Intel 80286 處理器存在勘誤,這個想法基本上只好被放棄。因此,OS/2 1.x——以及「標準」模式下的 Windows——都必須在真實模式下執行 DOS 程式。儘管如此,這個想法並未消失;它促使 Intel 在 80386 中引入了虛擬 8086 模式,最終得以用相對高效且有記載的方式實現「DOS Box」。

由於 LOADALL 不會對載入處理器暫存器的資料進行任何有效性檢查,因此可能載入一個正常情況下無法進入的處理器狀態,例如在 386 等級的 CPU 上同時使用真實模式(PE=0)與分頁(PG=1)。

線上模擬器(in-circuit emulator, ICE)是一種用於低階除錯的工具。在 Intel 80386 上,觸發 B6 位置上未記載的接腳會導致微處理器停止執行並進入 ICE 模式。微處理器會將其完整狀態儲存到一塊與正常系統記憶體隔離的記憶體區域。該區域的佈局適合 LOADALL 指令,而 ICE 程式碼正是使用此指令來恢復正常執行。

在後來的處理器中,這演變為系統管理模式(System Management Mode, SMM)。在 SMM 中,RSM 指令被用來從記憶體區域載入完整的 CPU 狀態。此記憶體區域的佈局與 LOADALL 指令所使用的相似。386 樣式的 LOADALL 指令也可以在 486 上執行,但僅限於 SMM 模式。在後來的處理器中,具有不同編碼的 RSM 指令取代了它的角色。

微軟的 Codeview 3.0 與 Borland 的 Turbo Debugger 2.0 能夠正確解碼 286 和 386 的 LOADALL 指令。

由於這兩種 LOADALL 指令從未被記載,且在後來的處理器中已不存在,其操作碼在 AMD64 架構中被重複使用。286 LOADALL 指令的操作碼 0F05 成為了 AMD64 的 SYSCALL 指令;386 LOADALL 指令的操作碼 0F07 則成為了 SYSRET 指令。這些定義甚至在 Intel 推出其 AMD64 的實作——Intel 64——後,也同樣應用於 Intel CPU。

80286

操作碼 0F05。該指令會從 0x00800–0x00866 位址讀取資料,無論區段暫存器的內容為何。

80286 的 LOADALL 指令不能用於從保護模式切換回真實模式(它無法清除 MSW 中的 PE 位元)。然而,使用 LOADALL 指令可以完全避免切換至保護模式的需要。

80386

操作碼 0F07。該指令從 ES:EDI 位址載入資料。它實際上使用的是 ES,而非 ES 描述符。

參見

  • Concurrent DOS 286
  • FlexOS 286
  • IBM 4680 OS

參考資料

延伸閱讀

Category:X86指令